mirror of
https://github.com/Ed94/Cog.git
synced 2026-08-02 04:38:15 +00:00
First Submit
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class CogAbility : ModuleRules
|
||||
{
|
||||
public CogAbility(ReadOnlyTargetRules Target) : base(Target)
|
||||
{
|
||||
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
|
||||
PublicIncludePaths.AddRange(
|
||||
new string[] {
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateIncludePaths.AddRange(
|
||||
new string[] {
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PublicDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core",
|
||||
"CogImgui",
|
||||
"CogDebug",
|
||||
"CogWindow",
|
||||
"GameplayAbilities",
|
||||
"GameplayTags",
|
||||
"NetCore",
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
DynamicallyLoadedModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#include "CogAbilityHelper.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
FString FCogAbilityHelper::CleanupName(FString Str)
|
||||
{
|
||||
Str.RemoveFromStart(TEXT("Default__"));
|
||||
Str.RemoveFromEnd(TEXT("_c"));
|
||||
return Str;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#include "CogAbilityModule.h"
|
||||
|
||||
#include "CogAbilityReplicator.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FCogAbilityModule"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogAbilityModule::StartupModule()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogAbilityModule::ShutdownModule()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
ACogAbilityReplicator* FCogAbilityModule::GetLocalReplicator()
|
||||
{
|
||||
return LocalReplicator;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogAbilityModule::SetLocalReplicator(ACogAbilityReplicator* Value)
|
||||
{
|
||||
LocalReplicator = Value;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
ACogAbilityReplicator* FCogAbilityModule::GetRemoteReplicator(const APlayerController* PlayerController)
|
||||
{
|
||||
for (ACogAbilityReplicator* Replicator : RemoteReplicators)
|
||||
{
|
||||
if (Replicator->GetPlayerController() == PlayerController)
|
||||
{
|
||||
return Replicator;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogAbilityModule::AddRemoteReplicator(ACogAbilityReplicator* Value)
|
||||
{
|
||||
RemoteReplicators.Add(Value);
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
||||
IMPLEMENT_MODULE(FCogAbilityModule, CogAbility)
|
||||
@@ -0,0 +1,378 @@
|
||||
#include "CogAbilityReplicator.h"
|
||||
|
||||
#include "AbilitySystemComponent.h"
|
||||
#include "AbilitySystemGlobals.h"
|
||||
#include "Components/SceneComponent.h"
|
||||
#include "EngineUtils.h"
|
||||
#include "GameplayEffect.h"
|
||||
#include "Net/Core/PushModel/PushModel.h"
|
||||
#include "Net/UnrealNetwork.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogAbilityReplicator::Create(APlayerController* Controller)
|
||||
{
|
||||
if (Controller->GetWorld()->GetNetMode() != NM_Client)
|
||||
{
|
||||
FActorSpawnParameters SpawnInfo;
|
||||
SpawnInfo.Owner = Controller;
|
||||
Controller->GetWorld()->SpawnActor<ACogAbilityReplicator>(SpawnInfo);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
ACogAbilityReplicator::ACogAbilityReplicator(const FObjectInitializer& ObjectInitializer)
|
||||
: Super(ObjectInitializer)
|
||||
{
|
||||
bReplicates = true;
|
||||
RootComponent = ObjectInitializer.CreateOptionalDefaultSubobject<USceneComponent>(this, TEXT("Root"));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogAbilityReplicator::GetLifetimeReplicatedProps(TArray< FLifetimeProperty >& OutLifetimeProps) const
|
||||
{
|
||||
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
||||
|
||||
FDoRepLifetimeParams Params;
|
||||
Params.bIsPushBased = true;
|
||||
Params.Condition = COND_OwnerOnly;
|
||||
|
||||
DOREPLIFETIME_WITH_PARAMS_FAST(ACogAbilityReplicator, TweakCurrentValues, Params);
|
||||
DOREPLIFETIME_WITH_PARAMS_FAST(ACogAbilityReplicator, TweakProfileIndex, Params);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogAbilityReplicator::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
OwnerPlayerController = Cast<APlayerController>(GetOwner());
|
||||
|
||||
if (OwnerPlayerController->IsLocalController())
|
||||
{
|
||||
FCogAbilityModule::Get().SetLocalReplicator(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
FCogAbilityModule::Get().AddRemoteReplicator(this);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogAbilityReplicator::ApplyCheat(AActor* CheatInstigator, const TArray<AActor*>& Targets, const FCogAbilityCheat& Cheat)
|
||||
{
|
||||
Server_ApplyCheat(CheatInstigator, Targets, Cheat);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogAbilityReplicator::Server_ApplyCheat_Implementation(const AActor* CheatInstigator, const TArray<AActor*>& Targets, const FCogAbilityCheat& Cheat) const
|
||||
{
|
||||
UAbilitySystemComponent* InstigatorAbilitySystem = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(CheatInstigator, true);
|
||||
if (InstigatorAbilitySystem == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (AActor* Target : Targets)
|
||||
{
|
||||
UAbilitySystemComponent* TargetAbilitySystem = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(Target, true);
|
||||
if (TargetAbilitySystem == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (TargetAbilitySystem->GetGameplayEffectCount(Cheat.Effect, nullptr) > 0)
|
||||
{
|
||||
TargetAbilitySystem->RemoveActiveGameplayEffectBySourceEffect(Cheat.Effect, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
FGameplayEffectContextHandle ContextHandle = InstigatorAbilitySystem->MakeEffectContext();
|
||||
ContextHandle.AddSourceObject(InstigatorAbilitySystem);
|
||||
FGameplayEffectSpecHandle SpecHandle = InstigatorAbilitySystem->MakeOutgoingSpec(Cheat.Effect, 1, ContextHandle);
|
||||
|
||||
if (FGameplayEffectSpec* EffectSpec = SpecHandle.Data.Get())
|
||||
{
|
||||
FHitResult HitResult;
|
||||
HitResult.HitObjectHandle = FActorInstanceHandle(Target);
|
||||
HitResult.Normal = FVector::ForwardVector;
|
||||
HitResult.ImpactNormal = FVector::ForwardVector;
|
||||
HitResult.Location = Target->GetActorLocation();
|
||||
HitResult.ImpactPoint = Target->GetActorLocation();
|
||||
HitResult.PhysMaterial = nullptr;
|
||||
ContextHandle.AddHitResult(HitResult, true);
|
||||
|
||||
InstigatorAbilitySystem->ApplyGameplayEffectSpecToTarget(*EffectSpec, TargetAbilitySystem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
bool ACogAbilityReplicator::IsCheatActive(const AActor* EffectTarget, const FCogAbilityCheat& Cheat)
|
||||
{
|
||||
if (Cheat.Effect == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
UAbilitySystemComponent* AbilitySystem = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(EffectTarget, true);
|
||||
if (AbilitySystem == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const int32 Count = AbilitySystem->GetGameplayEffectCount(Cheat.Effect, nullptr);
|
||||
return Count > 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogAbilityReplicator::GiveAbility(AActor* Target, TSubclassOf<UGameplayAbility> AbilityClass)
|
||||
{
|
||||
Server_GiveAbility(Target, AbilityClass);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogAbilityReplicator::Server_GiveAbility_Implementation(AActor* TargetActor, TSubclassOf<UGameplayAbility> AbilityClass) const
|
||||
{
|
||||
UAbilitySystemComponent* AbilitySystem = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(TargetActor, true);
|
||||
|
||||
if (AbilitySystem == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsValid(AbilityClass) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (AbilitySystem->IsOwnerActorAuthoritative() == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const FGameplayAbilitySpec Spec(AbilityClass, 1, INDEX_NONE, TargetActor);
|
||||
AbilitySystem->GiveAbility(Spec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogAbilityReplicator::ResetAllTweaks()
|
||||
{
|
||||
Server_ResetAllTweaks();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogAbilityReplicator::Server_ResetAllTweaks_Implementation()
|
||||
{
|
||||
TweakCurrentValues.Empty();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogAbilityReplicator::SetTweakValue(const UCogAbilityDataAsset_Tweaks* TweaksAsset, int32 TweakIndex, int32 TweakCategoryIndex, float Value)
|
||||
{
|
||||
Server_SetTweakValue(TweaksAsset, TweakIndex, TweakCategoryIndex, Value);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogAbilityReplicator::Server_SetTweakValue_Implementation(const UCogAbilityDataAsset_Tweaks* TweaksAsset, int32 TweakIndex, int32 TweakCategoryIndex, float Value)
|
||||
{
|
||||
if (TweaksAsset == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (TweaksAsset->Tweaks.IsValidIndex(TweakIndex) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (TweaksAsset->TweaksCategories.IsValidIndex(TweakCategoryIndex) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetTweakCurrentValue(TweaksAsset, TweakIndex, TweakCategoryIndex, Value);
|
||||
|
||||
const FCogAbilityTweak& Tweak = TweaksAsset->Tweaks[TweakIndex];
|
||||
|
||||
TArray<AActor*> Actors;
|
||||
GetActorsFromTweakCategory(TweaksAsset, TweakCategoryIndex, Actors);
|
||||
for (AActor* Actor : Actors)
|
||||
{
|
||||
ApplyTweakOnActor(Actor, Tweak, Value, TweaksAsset->SetByCallerMagnitudeTag);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogAbilityReplicator::ApplyAllTweaksOnActor(const UCogAbilityDataAsset_Tweaks* TweaksAsset, int32 TweakCategoryIndex, AActor* Actor)
|
||||
{
|
||||
if (TweaksAsset == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (TweaksAsset->TweaksCategories.IsValidIndex(TweakCategoryIndex) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int32 TweakIndex = 0;
|
||||
for (const FCogAbilityTweak& Tweak : TweaksAsset->Tweaks)
|
||||
{
|
||||
const float Value = GetTweakCurrentValue(TweaksAsset, TweakIndex, TweakCategoryIndex);
|
||||
ApplyTweakOnActor(Actor, Tweak, Value, TweaksAsset->SetByCallerMagnitudeTag);
|
||||
TweakIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogAbilityReplicator::ApplyTweakOnActor(AActor* Actor, const FCogAbilityTweak& Tweak, float Value, const FGameplayTag& SetByCallerMagnitudeTag)
|
||||
{
|
||||
UAbilitySystemComponent* AbilitySystem = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(Actor, true);
|
||||
if (AbilitySystem == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AbilitySystem->RemoveActiveGameplayEffectBySourceEffect(Tweak.Effect, nullptr);
|
||||
|
||||
if (Value != 0.0f)
|
||||
{
|
||||
FGameplayEffectSpecHandle SpecHandle = AbilitySystem->MakeOutgoingSpec(Tweak.Effect, 1, AbilitySystem->MakeEffectContext());
|
||||
|
||||
if (FGameplayEffectSpec* EffectSpec = SpecHandle.Data.Get())
|
||||
{
|
||||
EffectSpec->SetSetByCallerMagnitude(SetByCallerMagnitudeTag, (Value * Tweak.Multiplier) + Tweak.AddPostMultiplier);
|
||||
AbilitySystem->ApplyGameplayEffectSpecToSelf(*EffectSpec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
float ACogAbilityReplicator::GetTweakCurrentValue(const UCogAbilityDataAsset_Tweaks* TweaksAsset, int32 TweakIndex, int32 TweakCategoryIndex)
|
||||
{
|
||||
float* Value = GetTweakCurrentValuePtr(TweaksAsset, TweakIndex, TweakCategoryIndex);
|
||||
if (Value == nullptr)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return *Value;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
float* ACogAbilityReplicator::GetTweakCurrentValuePtr(const UCogAbilityDataAsset_Tweaks* TweaksAsset, int32 TweakIndex, int32 TweakCategoryIndex)
|
||||
{
|
||||
TweakCurrentValues.SetNum(TweaksAsset->Tweaks.Num() * TweaksAsset->TweaksCategories.Num());
|
||||
|
||||
const int32 Index = TweakIndex + (TweakCategoryIndex * TweaksAsset->Tweaks.Num());
|
||||
|
||||
if (TweakCurrentValues.IsValidIndex(Index) == false)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &TweakCurrentValues[Index];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogAbilityReplicator::SetTweakCurrentValue(const UCogAbilityDataAsset_Tweaks* TweaksAsset, int32 TweakIndex, int32 TweakCategoryIndex, float Value)
|
||||
{
|
||||
if (TweaksAsset == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TweakCurrentValues.SetNum(TweaksAsset->Tweaks.Num() * TweaksAsset->TweaksCategories.Num());
|
||||
|
||||
const int32 Index = TweakIndex + (TweakCategoryIndex * TweaksAsset->Tweaks.Num());
|
||||
if (TweakCurrentValues.IsValidIndex(TweakIndex) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TweakCurrentValues[Index] = Value;
|
||||
MARK_PROPERTY_DIRTY_FROM_NAME(ACogAbilityReplicator, TweakCurrentValues, this);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogAbilityReplicator::SetTweakProfile(const UCogAbilityDataAsset_Tweaks* TweaksAsset, int32 ProfileIndex)
|
||||
{
|
||||
Server_SetTweakProfile(TweaksAsset, ProfileIndex);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogAbilityReplicator::Server_SetTweakProfile_Implementation(const UCogAbilityDataAsset_Tweaks* TweaksAsset, int32 ProfileIndex)
|
||||
{
|
||||
if (TweaksAsset == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (TweaksAsset->TweakProfiles.IsValidIndex(ProfileIndex) == false)
|
||||
{
|
||||
ProfileIndex = INDEX_NONE;
|
||||
}
|
||||
|
||||
TweakProfileIndex = ProfileIndex;
|
||||
MARK_PROPERTY_DIRTY_FROM_NAME(ACogAbilityReplicator, TweakProfileIndex, this);
|
||||
|
||||
ResetAllTweaks();
|
||||
|
||||
if (TweaksAsset->TweakProfiles.IsValidIndex(TweakProfileIndex))
|
||||
{
|
||||
const FCogAbilityTweakProfile& TweakProfile = TweaksAsset->TweakProfiles[TweakProfileIndex];
|
||||
|
||||
for (const FCogAbilityTweakProfileValue& ProfileTweak : TweakProfile.Tweaks)
|
||||
{
|
||||
const int32 TweakIndex = TweaksAsset->Tweaks.IndexOfByPredicate([ProfileTweak](const FCogAbilityTweak& Tweak) { return ProfileTweak.Effect == Tweak.Effect; });
|
||||
const int32 TweakCategoryIndex = TweaksAsset->TweaksCategories.IndexOfByPredicate([ProfileTweak](const FCogAbilityTweakCategory& TweakCategory) { return ProfileTweak.CategoryId == TweakCategory.Id; });
|
||||
|
||||
if (TweakIndex != INDEX_NONE && TweakCategoryIndex != INDEX_NONE)
|
||||
{
|
||||
SetTweakCurrentValue(TweaksAsset, TweakIndex, TweakCategoryIndex, ProfileTweak.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int32 TweakCategoryIndex = 0; TweakCategoryIndex < TweaksAsset->TweaksCategories.Num(); ++TweakCategoryIndex)
|
||||
{
|
||||
TArray<AActor*> Actors;
|
||||
GetActorsFromTweakCategory(TweaksAsset, TweakCategoryIndex, Actors);
|
||||
|
||||
for (AActor* Actor : Actors)
|
||||
{
|
||||
ApplyAllTweaksOnActor(TweaksAsset, TweakCategoryIndex, Actor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogAbilityReplicator::GetActorsFromTweakCategory(const UCogAbilityDataAsset_Tweaks* TweaksAsset, int32 TweakCategoryIndex, TArray<AActor*>& Actors)
|
||||
{
|
||||
if (TweaksAsset == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (TweaksAsset->TweaksCategories.IsValidIndex(TweakCategoryIndex) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const FCogAbilityTweakCategory& TweakCategory = TweaksAsset->TweaksCategories[TweakCategoryIndex];
|
||||
|
||||
for (TActorIterator<AActor> It(GetWorld(), TweakCategory.ActorClass); It; ++It)
|
||||
{
|
||||
AActor* Actor = *It;
|
||||
if (UAbilitySystemComponent* AbilitySystem = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(Actor, true))
|
||||
{
|
||||
const bool bHasRequiredTags = AbilitySystem->HasAllMatchingGameplayTags(TweakCategory.RequiredTags);
|
||||
const bool bHasIgnoredTags = AbilitySystem->HasAnyMatchingGameplayTags(TweakCategory.IgnoredTags);
|
||||
if (bHasRequiredTags && bHasIgnoredTags == false)
|
||||
{
|
||||
Actors.AddUnique(Actor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,440 @@
|
||||
#include "CogAbilityWindow_Abilities.h"
|
||||
|
||||
#include "CogAbilityDataAsset_Abilities.h"
|
||||
#include "CogAbilityHelper.h"
|
||||
#include "CogWindowWidgets.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui_internal.h"
|
||||
|
||||
ImVec4 ActiveColor(1.0f, 0.8f, 0.0f, 1.0f);
|
||||
ImVec4 DeactiveColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Abilities::PreRender(ImGuiWindowFlags& WindowFlags)
|
||||
{
|
||||
WindowFlags = ImGuiWindowFlags_MenuBar;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Abilities::RenderTick(float DetlaTime)
|
||||
{
|
||||
Super::RenderTick(DetlaTime);
|
||||
|
||||
RenderOpenAbilities();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Abilities::RenderOpenAbilities()
|
||||
{
|
||||
AActor* Selection = GetSelection();
|
||||
if (Selection == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UAbilitySystemComponent* AbilitySystemComponent = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(Selection, true);
|
||||
if (AbilitySystemComponent == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = OpenedAbilities.Num() - 1; i >= 0; --i)
|
||||
{
|
||||
FGameplayAbilitySpecHandle Handle = OpenedAbilities[i];
|
||||
|
||||
FGameplayAbilitySpec* Spec = AbilitySystemComponent->FindAbilitySpecFromHandle(Handle);
|
||||
if (Spec == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
UGameplayAbility* Ability = Spec->GetPrimaryInstance();
|
||||
if (Ability == nullptr)
|
||||
{
|
||||
Ability = Spec->Ability;
|
||||
}
|
||||
|
||||
bool Open = true;
|
||||
if (ImGui::Begin(TCHAR_TO_ANSI(*GetAbilityName(Ability)), &Open))
|
||||
{
|
||||
RenderAbilityInfo(*Spec);
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
if (Open == false)
|
||||
{
|
||||
OpenedAbilities.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Abilities::RenderContent()
|
||||
{
|
||||
Super::RenderContent();
|
||||
|
||||
AActor* Selection = GetSelection();
|
||||
if (Selection == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UAbilitySystemComponent* AbilitySystemComponent = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(Selection, true);
|
||||
if (AbilitySystemComponent == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RenderAbiltiesMenu(Selection);
|
||||
|
||||
//TArray<FGameplayAbilitySpec>& Abilities = AbilitySystemComponent->GetActivatableAbilities();
|
||||
//static int FocusedAbilityIndex = INDEX_NONE;
|
||||
//if (FocusedAbilityIndex != INDEX_NONE && FocusedAbilityIndex < Abilities.Num())
|
||||
//{
|
||||
// RenderAbilityInfo(Abilities[FocusedAbilityIndex]);
|
||||
// if (ImGui::Button("Close", ImVec2(-1, 0)))
|
||||
// {
|
||||
// FocusedAbilityIndex = INDEX_NONE;
|
||||
// }
|
||||
// ImGui::Spacing();
|
||||
//}
|
||||
|
||||
RenderAbilitiesTable(*AbilitySystemComponent);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Abilities::RenderAbiltiesMenu(AActor* Selection)
|
||||
{
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
if (ImGui::BeginMenu("Add"))
|
||||
{
|
||||
if (AbilitiesAsset != nullptr)
|
||||
{
|
||||
int Index = 0;
|
||||
for (TSubclassOf<UGameplayAbility> AbilityClass : AbilitiesAsset->Abilities)
|
||||
{
|
||||
ImGui::PushID(Index);
|
||||
|
||||
if (ImGui::MenuItem(TCHAR_TO_ANSI(*GetNameSafe(AbilityClass))))
|
||||
{
|
||||
FCogAbilityModule& Module = FCogAbilityModule::Get();
|
||||
if (ACogAbilityReplicator* Replicator = Module.GetLocalReplicator())
|
||||
{
|
||||
Replicator->GiveAbility(Selection, AbilityClass);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
Index++;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Abilities::RenderAbilitiesTable(UAbilitySystemComponent& AbilitySystemComponent)
|
||||
{
|
||||
TArray<FGameplayAbilitySpec>& Abilities = AbilitySystemComponent.GetActivatableAbilities();
|
||||
|
||||
if (ImGui::BeginTable("Abilities", 4, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_NoBordersInBodyUntilResize | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersH | ImGuiTableFlags_NoBordersInBody))
|
||||
{
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("Ability");
|
||||
ImGui::TableSetupColumn("Level");
|
||||
ImGui::TableSetupColumn("Input");
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
static int SelectedIndex = -1;
|
||||
int Index = 0;
|
||||
|
||||
for (FGameplayAbilitySpec& Spec : Abilities)
|
||||
{
|
||||
UGameplayAbility* Ability = Spec.GetPrimaryInstance();
|
||||
if (Ability == nullptr)
|
||||
{
|
||||
Ability = Spec.Ability;
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
|
||||
ImGui::PushID(Index);
|
||||
|
||||
ImVec4 Color = Spec.ActiveCount > 0 ? ActiveColor : DeactiveColor;
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, Color);
|
||||
|
||||
//------------------------
|
||||
// Activation
|
||||
//------------------------
|
||||
ImGui::TableNextColumn();
|
||||
FCogWindowWidgets::PushStyleCompact();
|
||||
bool IsActive = Spec.IsActive();
|
||||
if (ImGui::Checkbox("##Activation", &IsActive))
|
||||
{
|
||||
AbilityHandleToActivate = Spec.Handle;
|
||||
}
|
||||
FCogWindowWidgets::PopStyleCompact();
|
||||
|
||||
//------------------------
|
||||
// Name
|
||||
//------------------------
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
if (ImGui::Selectable(TCHAR_TO_ANSI(*GetAbilityName(Ability)), SelectedIndex == Index, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap | ImGuiSelectableFlags_AllowDoubleClick))
|
||||
{
|
||||
SelectedIndex = Index;
|
||||
|
||||
if (ImGui::IsMouseDoubleClicked(0))
|
||||
{
|
||||
OpenAbility(Spec.Handle);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopStyleColor(1);
|
||||
|
||||
//------------------------
|
||||
// Popup
|
||||
//------------------------
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
FCogWindowWidgets::BeginTableTooltip();
|
||||
RenderAbilityInfo(Spec);
|
||||
FCogWindowWidgets::EndTableTooltip();
|
||||
}
|
||||
|
||||
//------------------------
|
||||
// ContextMenu
|
||||
//------------------------
|
||||
RenderAbilityContextMenu(AbilitySystemComponent, Spec, Index);
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, Color);
|
||||
|
||||
//------------------------
|
||||
// Level
|
||||
//------------------------
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", Spec.Level);
|
||||
|
||||
//------------------------
|
||||
// InputPressed
|
||||
//------------------------
|
||||
ImGui::TableNextColumn();
|
||||
if (Spec.InputPressed > 0)
|
||||
{
|
||||
ImGui::Text("%d", Spec.InputPressed);
|
||||
}
|
||||
|
||||
ImGui::PopStyleColor(1);
|
||||
|
||||
ImGui::PopID();
|
||||
Index++;
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Abilities::RenderAbilityContextMenu(UAbilitySystemComponent& AbilitySystemComponent, FGameplayAbilitySpec& Spec, int Index)
|
||||
{
|
||||
if (ImGui::BeginPopupContextItem())
|
||||
{
|
||||
bool bOpen = OpenedAbilities.Contains(Spec.Handle);
|
||||
if (ImGui::Checkbox("Open", &bOpen))
|
||||
{
|
||||
if (bOpen)
|
||||
{
|
||||
OpenAbility(Spec.Handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
CloseAbility(Spec.Handle);
|
||||
}
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
//if (ImGui::Button("Open Properties"))
|
||||
//{
|
||||
// GetOwner()->GetPropertyGrid()->Open(BaseAbility);
|
||||
// ImGui::CloseCurrentPopup();
|
||||
//}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Abilities::OpenAbility(FGameplayAbilitySpecHandle Handle)
|
||||
{
|
||||
OpenedAbilities.AddUnique(Handle);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Abilities::CloseAbility(FGameplayAbilitySpecHandle Handle)
|
||||
{
|
||||
OpenedAbilities.Remove(Handle);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
FString UCogAbilityWindow_Abilities::GetAbilityName(const UGameplayAbility* Ability)
|
||||
{
|
||||
if (Ability == nullptr)
|
||||
{
|
||||
return FString("NULL");
|
||||
}
|
||||
|
||||
FString Str = FCogAbilityHelper::CleanupName(Ability->GetName());
|
||||
return Str;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Abilities::RenderAbilityInfo(FGameplayAbilitySpec& Spec)
|
||||
{
|
||||
UGameplayAbility* Ability = Spec.GetPrimaryInstance();
|
||||
if (Ability == nullptr)
|
||||
{
|
||||
Ability = Spec.Ability;
|
||||
}
|
||||
|
||||
if (ImGui::BeginTable("Ability", 2, ImGuiTableFlags_Borders))
|
||||
{
|
||||
const ImVec4 TextColor(1.0f, 1.0f, 1.0f, 0.5f);
|
||||
|
||||
ImGui::TableSetupColumn("Property");
|
||||
ImGui::TableSetupColumn("Value");
|
||||
|
||||
//------------------------
|
||||
// Name
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "Name");
|
||||
ImGui::TableNextColumn();
|
||||
ImVec4 Color = Spec.ActiveCount > 0 ? ActiveColor : DeactiveColor;
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, Color);
|
||||
ImGui::Text("%s", TCHAR_TO_ANSI(*GetAbilityName(Ability)));
|
||||
ImGui::PopStyleColor(1);
|
||||
|
||||
//------------------------
|
||||
// Activation
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "Activation");
|
||||
ImGui::TableNextColumn();
|
||||
FCogWindowWidgets::PushStyleCompact();
|
||||
bool IsActive = Spec.IsActive();
|
||||
if (ImGui::Checkbox("##Activation", &IsActive))
|
||||
{
|
||||
AbilityHandleToActivate = Spec.Handle;
|
||||
}
|
||||
FCogWindowWidgets::PopStyleCompact();
|
||||
|
||||
//------------------------
|
||||
// Active Count
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "Active Count");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%u", Spec.ActiveCount);
|
||||
|
||||
//------------------------
|
||||
// Handle
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "Handle");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", TCHAR_TO_ANSI(*Spec.Handle.ToString()));
|
||||
|
||||
//------------------------
|
||||
// Level
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "Level");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", Spec.Level);
|
||||
|
||||
//------------------------
|
||||
// InputID
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "InputID");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", Spec.InputID);
|
||||
|
||||
//------------------------
|
||||
// InputPressed
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "InputPressed");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", Spec.InputPressed);
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Abilities::GameTick(float DeltaTime)
|
||||
{
|
||||
if (AbilityHandleToActivate.IsValid())
|
||||
{
|
||||
ProcessAbilityActivation(AbilityHandleToActivate);
|
||||
AbilityHandleToActivate = FGameplayAbilitySpecHandle();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Abilities::ProcessAbilityActivation(FGameplayAbilitySpecHandle Handle)
|
||||
{
|
||||
AActor* Selection = GetSelection();
|
||||
if (Selection == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UAbilitySystemComponent* AbilitySystemComponent = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(Selection, true);
|
||||
if (AbilitySystemComponent == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FGameplayAbilitySpec* Spec = AbilitySystemComponent->FindAbilitySpecFromHandle(Handle);
|
||||
if (Spec == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Spec->IsActive())
|
||||
{
|
||||
DeactivateAbility(*AbilitySystemComponent, *Spec);
|
||||
}
|
||||
else
|
||||
{
|
||||
ActivateAbility(*AbilitySystemComponent, *Spec);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Abilities::ActivateAbility(UAbilitySystemComponent& AbilitySystemComponent, FGameplayAbilitySpec& Spec)
|
||||
{
|
||||
Spec.InputPressed = true;
|
||||
AbilitySystemComponent.TryActivateAbility(Spec.Handle);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Abilities::DeactivateAbility(UAbilitySystemComponent& AbilitySystemComponent, FGameplayAbilitySpec& Spec)
|
||||
{
|
||||
Spec.InputPressed = false;
|
||||
AbilitySystemComponent.CancelAbilityHandle(Spec.Handle);
|
||||
}
|
||||
@@ -0,0 +1,351 @@
|
||||
#include "CogAbilityWindow_Attributes.h"
|
||||
|
||||
#include "AbilitySystemComponent.h"
|
||||
#include "AbilitySystemGlobals.h"
|
||||
#include "CogAbilityHelper.h"
|
||||
#include "CogWindowWidgets.h"
|
||||
#include "AttributeSet.h"
|
||||
#include "EngineUtils.h"
|
||||
#include "GameFramework/Character.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCogAbilityWindow_Attributes::UCogAbilityWindow_Attributes()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Attributes::PreRender(ImGuiWindowFlags& WindowFlags)
|
||||
{
|
||||
WindowFlags = ImGuiWindowFlags_MenuBar;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
static void DrawAttributeInfo(const UAbilitySystemComponent& AbilitySystemComponent, const FGameplayAttribute& Attribute)
|
||||
{
|
||||
if (ImGui::BeginTable("Attribute", 2, ImGuiTableFlags_Borders))
|
||||
{
|
||||
const ImVec4 TextColor(1.0f, 1.0f, 1.0f, 0.5f);
|
||||
|
||||
ImGui::TableSetupColumn("Property");
|
||||
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
|
||||
|
||||
const float BaseValue = AbilitySystemComponent.GetNumericAttributeBase(Attribute);
|
||||
const float CurrentValue = AbilitySystemComponent.GetNumericAttribute(Attribute);
|
||||
|
||||
ImVec4 Color;
|
||||
if (CurrentValue > BaseValue)
|
||||
{
|
||||
Color = ImVec4(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
}
|
||||
else if (CurrentValue < BaseValue)
|
||||
{
|
||||
Color = ImVec4(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
Color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
//------------------------
|
||||
// Name
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "Name");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", TCHAR_TO_ANSI(*Attribute.GetName()));
|
||||
|
||||
//------------------------
|
||||
// Base Value
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "Base Value");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%0.2f", BaseValue);
|
||||
|
||||
//------------------------
|
||||
// Current Value
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "Current Value");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, Color);
|
||||
ImGui::Text("%0.2f", CurrentValue);
|
||||
ImGui::PopStyleColor(1);
|
||||
|
||||
//------------------------
|
||||
// Modifiers
|
||||
//------------------------
|
||||
FGameplayEffectQuery Query;
|
||||
for (const FActiveGameplayEffectHandle& ActiveHandle : AbilitySystemComponent.GetActiveEffects(Query))
|
||||
{
|
||||
const FActiveGameplayEffect* ActiveEffect = AbilitySystemComponent.GetActiveGameplayEffect(ActiveHandle);
|
||||
if (ActiveEffect == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < ActiveEffect->Spec.Modifiers.Num(); ++i)
|
||||
{
|
||||
const FModifierSpec& ModSpec = ActiveEffect->Spec.Modifiers[i];
|
||||
const FGameplayModifierInfo& ModInfo = ActiveEffect->Spec.Def->Modifiers[i];
|
||||
|
||||
if (ModInfo.Attribute == Attribute)
|
||||
{
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "Effect");
|
||||
ImGui::TextColored(TextColor, "Operation");
|
||||
ImGui::TextColored(TextColor, "Magnitude");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", TCHAR_TO_ANSI(*FCogAbilityHelper::CleanupName(GetNameSafe(ActiveEffect->Spec.Def))));
|
||||
ImGui::Text("%s", TCHAR_TO_ANSI(*EGameplayModOpToString(ModInfo.ModifierOp)));
|
||||
ImGui::Text("%0.2f", ModSpec.GetEvaluatedMagnitude());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Attributes::RenderContent()
|
||||
{
|
||||
Super::RenderContent();
|
||||
|
||||
UAbilitySystemComponent* AbilitySystemComponent = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(GetSelection(), true);
|
||||
if (AbilitySystemComponent == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
if (ImGui::BeginMenu("Options"))
|
||||
{
|
||||
ImGui::Checkbox("Sort by name", &bSortByNameSetting);
|
||||
ImGui::Checkbox("Group by attribute set", &bGroupByAttributeSetSetting);
|
||||
ImGui::Checkbox("Group by category", &bGroupByCategorySetting);
|
||||
ImGui::Checkbox("Show Only Modified", &bShowOnlyModified);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
FCogWindowWidgets::MenuSearchBar(Filter);
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
bool bGroupByAttributeSet = Filter.IsActive() == false && bShowOnlyModified == false && bGroupByAttributeSetSetting;
|
||||
bool bGroupByCategory = Filter.IsActive() == false && bShowOnlyModified == false && bGroupByCategorySetting;
|
||||
|
||||
if (ImGui::BeginTable("Attributes", 3, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_NoBordersInBodyUntilResize | ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable))
|
||||
{
|
||||
ImGui::TableSetupScrollFreeze(0, 1);
|
||||
ImGui::TableSetupColumn("Attribute");
|
||||
ImGui::TableSetupColumn("Base");
|
||||
ImGui::TableSetupColumn("Current");
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
static int Selected = -1;
|
||||
int Index = 0;
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// Draw all the attribute sets
|
||||
//------------------------------------------------------------------------------------------
|
||||
for (const UAttributeSet* Set : AbilitySystemComponent->GetSpawnedAttributes())
|
||||
{
|
||||
//------------------------------------------------------------------------------------------
|
||||
// Add an tree node categories are shown
|
||||
//------------------------------------------------------------------------------------------
|
||||
bool bOpenAttributeSet = true;
|
||||
if (bGroupByAttributeSet)
|
||||
{
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
bOpenAttributeSet = ImGui::TreeNodeEx(TCHAR_TO_ANSI(*Set->GetName()), ImGuiTreeNodeFlags_SpanFullWidth);
|
||||
}
|
||||
|
||||
if (bOpenAttributeSet)
|
||||
{
|
||||
TArray<FGameplayAttribute> AllAttributes;
|
||||
for (TFieldIterator<FProperty> It(Set->GetClass()); It; ++It)
|
||||
{
|
||||
FGameplayAttribute Attribute = *It;
|
||||
if (Attribute.IsValid())
|
||||
{
|
||||
AllAttributes.Add(Attribute);
|
||||
}
|
||||
}
|
||||
|
||||
TMap<FString, TArray<FGameplayAttribute>> AttributesByCategory;
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// Sort attributes by category to make sure categories are displayed in alphabetical order
|
||||
//------------------------------------------------------------------------------------------
|
||||
#if WITH_EDITORONLY_DATA
|
||||
if (bGroupByCategory)
|
||||
{
|
||||
AllAttributes.Sort([](const FGameplayAttribute& Attribute1, const FGameplayAttribute& Attribute2)
|
||||
{
|
||||
FString Category1 = Attribute1.GetUProperty() != nullptr ? Attribute1.GetUProperty()->GetMetaData(TEXT("Category")) : "";
|
||||
FString Category2 = Attribute2.GetUProperty() != nullptr ? Attribute2.GetUProperty()->GetMetaData(TEXT("Category")) : "";
|
||||
return Category1.Compare(Category2) < 0;
|
||||
});
|
||||
}
|
||||
#endif //WITH_EDITORONLY_DATA
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// If required, group by category, or put every attribute into the default category
|
||||
// if this code is changed verify the SortByName works in all modes
|
||||
//------------------------------------------------------------------------------------------
|
||||
for (FGameplayAttribute& Attribute : AllAttributes)
|
||||
{
|
||||
FString Category = TEXT("Default");
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
if (bGroupByCategory)
|
||||
{
|
||||
FString ActualCategory = Attribute.GetUProperty() != nullptr ? Attribute.GetUProperty()->GetMetaData(TEXT("Category")) : "";
|
||||
if (ActualCategory.IsEmpty() == false)
|
||||
{
|
||||
Category = ActualCategory;
|
||||
}
|
||||
}
|
||||
#endif //WITH_EDITORONLY_DATA
|
||||
|
||||
AttributesByCategory.FindOrAdd(Category).Add(Attribute);
|
||||
}
|
||||
|
||||
for (auto& It : AttributesByCategory)
|
||||
{
|
||||
//------------------------------------------------------------------------------------------
|
||||
// Add a tree node with the name of the category if categories are shown
|
||||
//------------------------------------------------------------------------------------------
|
||||
bool bOpenCategory = true;
|
||||
if (bGroupByCategory)
|
||||
{
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
bOpenCategory = ImGui::TreeNodeEx(TCHAR_TO_ANSI(*It.Key), ImGuiTreeNodeFlags_SpanFullWidth);
|
||||
}
|
||||
|
||||
if (bOpenCategory)
|
||||
{
|
||||
TArray<FGameplayAttribute>& AttributesInCategory = It.Value;
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// Sort attributes within a category by their name
|
||||
//------------------------------------------------------------------------------------------
|
||||
if (bSortByNameSetting)
|
||||
{
|
||||
AttributesInCategory.Sort([](const FGameplayAttribute& Lhs, const FGameplayAttribute& Rhs)
|
||||
{
|
||||
return Lhs.GetName().Compare(Rhs.GetName()) < 0;
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// Draw all the attribute of the current category of the current attribute set
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
for (const FGameplayAttribute& Attribute : AttributesInCategory)
|
||||
{
|
||||
if (!Attribute.IsValid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const char* AttributeName = TCHAR_TO_ANSI(*Attribute.GetName());
|
||||
|
||||
if (Filter.PassFilter(AttributeName) == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const float BaseValue = AbilitySystemComponent->GetNumericAttributeBase(Attribute);
|
||||
const float CurrentValue = AbilitySystemComponent->GetNumericAttribute(Attribute);
|
||||
|
||||
if (bShowOnlyModified && FMath::IsNearlyEqual(CurrentValue, BaseValue))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
|
||||
ImVec4 Color;
|
||||
if (CurrentValue > BaseValue)
|
||||
{
|
||||
Color = ImVec4(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
}
|
||||
else if (CurrentValue < BaseValue)
|
||||
{
|
||||
Color = ImVec4(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
Color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, Color);
|
||||
|
||||
//------------------------
|
||||
// Name
|
||||
//------------------------
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("");
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Selectable(AttributeName, Selected == Index, ImGuiSelectableFlags_SpanAllColumns))
|
||||
{
|
||||
Selected = Index;
|
||||
}
|
||||
ImGui::PopStyleColor(1);
|
||||
|
||||
//------------------------
|
||||
// Popup
|
||||
//------------------------
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
FCogWindowWidgets::BeginTableTooltip();
|
||||
DrawAttributeInfo(*AbilitySystemComponent, Attribute);
|
||||
FCogWindowWidgets::EndTableTooltip();
|
||||
}
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, Color);
|
||||
|
||||
//------------------------
|
||||
// Base Value
|
||||
//------------------------
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%.2f", BaseValue);
|
||||
|
||||
//------------------------
|
||||
// Current Value
|
||||
//------------------------
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%.2f", CurrentValue);
|
||||
|
||||
ImGui::PopStyleColor(1);
|
||||
|
||||
Index++;
|
||||
}
|
||||
}
|
||||
|
||||
if (bOpenCategory && bGroupByCategory)
|
||||
{
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bOpenAttributeSet && bGroupByAttributeSet)
|
||||
{
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
#include "CogAbilityWindow_Cheats.h"
|
||||
|
||||
#include "CogAbilityDataAsset_Cheats.h"
|
||||
#include "CogDebugAllegianceInterface.h"
|
||||
#include "CogDebugDraw.h"
|
||||
#include "EngineUtils.h"
|
||||
#include "GameFramework/Character.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui_internal.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCogAbilityWindow_Cheats::UCogAbilityWindow_Cheats()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Cheats::RenderContent()
|
||||
{
|
||||
Super::RenderContent();
|
||||
|
||||
AActor* SelectedActor = GetSelection();
|
||||
if (SelectedActor == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (CheatsAsset == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
APawn* LocalPawn = GetLocalPlayerPawn();
|
||||
|
||||
if (ImGui::BeginTable("Cheats", 2, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_NoBordersInBodyUntilResize))
|
||||
{
|
||||
ImGui::TableSetupColumn("Toggle", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableSetupColumn("Instant", ImGuiTableColumnFlags_WidthStretch);
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
int Index = 0;
|
||||
for (const FCogAbilityCheat& CheatEffect : CheatsAsset->PersistentEffects)
|
||||
{
|
||||
ImGui::PushID(Index);
|
||||
AddCheat(LocalPawn, SelectedActor, CheatEffect, true);
|
||||
ImGui::PopID();
|
||||
Index++;
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
for (const FCogAbilityCheat& CheatEffect : CheatsAsset->InstantEffects)
|
||||
{
|
||||
ImGui::PushID(Index);
|
||||
AddCheat(LocalPawn, SelectedActor, CheatEffect, false);
|
||||
ImGui::PopID();
|
||||
Index++;
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Cheats::AddCheat(AActor* CheatInstigator, AActor* SelectedActor, const FCogAbilityCheat& Cheat, bool IsPersistent)
|
||||
{
|
||||
if (Cheat.Effect == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const FGameplayTagContainer& Tags = Cheat.Effect->GetDefaultObject<UGameplayEffect>()->InheritableGameplayEffectTags.CombinedTags;
|
||||
|
||||
FLinearColor Color;
|
||||
if (Tags.HasTag(CheatsAsset->NegativeEffectTag))
|
||||
{
|
||||
Color = CheatsAsset->NegativeEffectColor;
|
||||
}
|
||||
else if (Tags.HasTag(CheatsAsset->PositiveEffectTag))
|
||||
{
|
||||
Color = CheatsAsset->PositiveEffectColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
Color = CheatsAsset->NeutralEffectColor;
|
||||
}
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(Color.R, Color.G, Color.B, 0.2f * Color.A));
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(Color.R, Color.G, Color.B, 0.3f * Color.A));
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(Color.R, Color.G, Color.B, 0.5f * Color.A));
|
||||
ImGui::PushStyleColor(ImGuiCol_CheckMark, ImVec4(Color.R, Color.G, Color.B, 0.8f * Color.A));
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(Color.R, Color.G, Color.B, 0.2f * Color.A));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(Color.R, Color.G, Color.B, 0.3f * Color.A));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(Color.R, Color.G, Color.B, 0.5f * Color.A));
|
||||
|
||||
if (IsPersistent)
|
||||
{
|
||||
bool isEnabled = ACogAbilityReplicator::IsCheatActive(SelectedActor, Cheat);
|
||||
if (ImGui::Checkbox(TCHAR_TO_ANSI(*Cheat.Name), &isEnabled))
|
||||
{
|
||||
RequestCheat(CheatInstigator, SelectedActor, Cheat);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ImGui::Button(TCHAR_TO_ANSI(*Cheat.Name), ImVec2(-1, 0)))
|
||||
{
|
||||
RequestCheat(CheatInstigator, SelectedActor, Cheat);
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
const bool IsShiftDown = (ImGui::GetCurrentContext()->IO.KeyMods & ImGuiMod_Shift) != 0;
|
||||
const bool IsAltDown = (ImGui::GetCurrentContext()->IO.KeyMods & ImGuiMod_Alt) != 0;
|
||||
const bool IsControlDown = (ImGui::GetCurrentContext()->IO.KeyMods & ImGuiMod_Ctrl) != 0;
|
||||
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, IsShiftDown || IsAltDown || IsControlDown ? 0.5f : 1.0f), "On Selection");
|
||||
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, IsShiftDown ? 1.0f : 0.5f), "On Enemies [SHIFT]");
|
||||
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, IsAltDown ? 1.0f : 0.5f), "On Allies [ALT]");
|
||||
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, IsControlDown ? 1.0f : 0.5f), "On Controlled [CTRL]");
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
ImGui::PopStyleColor(7);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Cheats::RequestCheat(AActor* CheatInstigator, AActor* SelectedActor, const FCogAbilityCheat& Cheat)
|
||||
{
|
||||
const bool IsShiftDown = (ImGui::GetCurrentContext()->IO.KeyMods & ImGuiMod_Shift) != 0;
|
||||
const bool IsAltDown = (ImGui::GetCurrentContext()->IO.KeyMods & ImGuiMod_Alt) != 0;
|
||||
const bool IsControlDown = (ImGui::GetCurrentContext()->IO.KeyMods & ImGuiMod_Ctrl) != 0;
|
||||
|
||||
TArray<AActor*> Actors;
|
||||
|
||||
if (IsControlDown)
|
||||
{
|
||||
Actors.Add(CheatInstigator);
|
||||
}
|
||||
|
||||
if (IsShiftDown || IsAltDown)
|
||||
{
|
||||
for (TActorIterator<ACharacter> It(GetWorld(), ACharacter::StaticClass()); It; ++It)
|
||||
{
|
||||
if (AActor* OtherActor = *It)
|
||||
{
|
||||
ECogAllegiance Allegiance = ECogAllegiance::Enemy;
|
||||
|
||||
if (ICogAllegianceInterface* AllegianceInterface = Cast<ICogAllegianceInterface>(OtherActor))
|
||||
{
|
||||
AllegianceInterface->GetAllegiance(CheatInstigator);
|
||||
}
|
||||
|
||||
if ((IsShiftDown && (Allegiance == ECogAllegiance::Enemy))
|
||||
|| (IsAltDown && (Allegiance == ECogAllegiance::Ally)))
|
||||
{
|
||||
Actors.Add(OtherActor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((IsControlDown || IsShiftDown || IsAltDown) == false)
|
||||
{
|
||||
Actors.Add(SelectedActor);
|
||||
}
|
||||
|
||||
FCogAbilityModule& Module = FCogAbilityModule::Get();
|
||||
if (ACogAbilityReplicator* Replicator = Module.GetLocalReplicator())
|
||||
{
|
||||
Replicator->ApplyCheat(CheatInstigator, Actors, Cheat);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,275 @@
|
||||
#include "CogAbilityWindow_Damages.h"
|
||||
|
||||
#include "CogAbilityDamageActorInterface.h"
|
||||
#include "CogImguiHelper.h"
|
||||
#include "imgui.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
float FCogDamageStats::MaxDurationSetting = 0.0f;
|
||||
float FCogDamageStats::RestartDelaySetting = 5.0f;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogDamageInstance::Restart()
|
||||
{
|
||||
DamageLast = 0.0f;
|
||||
DamageMin = 0.0f;
|
||||
DamageMax = 0.0f;
|
||||
DamagePerSecond = 0.0f;
|
||||
DamagePerFrame = 0.0f;
|
||||
DamageTotal = 0.0f;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogDamageInstance::AddDamage(const float Damage)
|
||||
{
|
||||
DamageLast = Damage;
|
||||
DamageMin = DamageMin == 0.0f ? Damage : FMath::Min(DamageMin, Damage);
|
||||
DamageMax = FMath::Max(DamageMax, Damage);
|
||||
DamagePerFrame += Damage;
|
||||
DamageTotal += Damage;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogDamageInstance::UpdateDamagePerSecond(const float Duration)
|
||||
{
|
||||
DamagePerSecond = Duration > 1.0f ? DamageTotal / Duration : DamageTotal;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogDamageStats::Restart()
|
||||
{
|
||||
Count = 0;
|
||||
Crits = 0;
|
||||
TotalCritChances = 0.0f;
|
||||
|
||||
IsInProgress = false;
|
||||
Timer = 0.0f;
|
||||
RestartTimer = 0.0f;
|
||||
|
||||
Mitigated.Restart();
|
||||
Unmitigated.Restart();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogDamageStats::AddDamage(const float InMitigatedDamage, const float InUnmitigatedDamage, const bool bIsCrit)
|
||||
{
|
||||
// If the max duration is reached, stop adding
|
||||
if (MaxDuration != 0 && Timer >= MaxDuration)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IsInProgress = true;
|
||||
Count++;
|
||||
Crits += bIsCrit ? 1 : 0;
|
||||
MaxDuration = MaxDurationSetting;
|
||||
|
||||
Mitigated.AddDamage(InMitigatedDamage);
|
||||
Unmitigated.AddDamage(InUnmitigatedDamage);
|
||||
Mitigated.UpdateDamagePerSecond(Timer);
|
||||
Unmitigated.UpdateDamagePerSecond(Timer);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogDamageStats::Tick(const float DeltaSeconds)
|
||||
{
|
||||
if (IsInProgress)
|
||||
{
|
||||
// If the max duration is reached, stop increasing time.
|
||||
if (MaxDuration <= 0 || Timer < MaxDuration)
|
||||
{
|
||||
Timer += DeltaSeconds;
|
||||
}
|
||||
else
|
||||
{
|
||||
IsInProgress = false;
|
||||
Timer = MaxDuration;
|
||||
Mitigated.UpdateDamagePerSecond(Timer);
|
||||
Unmitigated.UpdateDamagePerSecond(Timer);
|
||||
}
|
||||
}
|
||||
|
||||
if (RestartDelaySetting > 0.0f)
|
||||
{
|
||||
if (Unmitigated.DamagePerFrame == 0.0f)
|
||||
{
|
||||
RestartTimer += DeltaSeconds;
|
||||
if (RestartTimer > RestartDelaySetting)
|
||||
{
|
||||
Restart();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RestartTimer = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
Mitigated.DamagePerFrame = 0.0f;
|
||||
Unmitigated.DamagePerFrame = 0.0f;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
static void DrawRow(const char* Title, float MitigatedValue, float UnmitigatedValue, ImVec4 Color)
|
||||
{
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Selectable(Title, false, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap | ImGuiSelectableFlags_AllowDoubleClick);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(Color, "%.1f", MitigatedValue);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%.1f", UnmitigatedValue);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%.0f%%", UnmitigatedValue <= 0 ? 0.0 : 100.0f * (1.0f - (MitigatedValue / UnmitigatedValue)));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
static void DrawDamages(FCogDamageStats& Damage)
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, IM_COL32(150, 150, 150, 60));
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, IM_COL32(150, 150, 150, 80));
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, IM_COL32(150, 150, 150, 120));
|
||||
ImGui::PushStyleColor(ImGuiCol_CheckMark, IM_COL32(150, 150, 150, 200));
|
||||
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, IM_COL32(120, 120, 120, 255));
|
||||
|
||||
if (ImGui::BeginTable("Damages", 4, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_NoBordersInBodyUntilResize | ImGuiTableFlags_RowBg))
|
||||
{
|
||||
ImGui::TableSetupColumn("");
|
||||
ImGui::TableSetupColumn("Mitigated");
|
||||
ImGui::TableSetupColumn("Unmitigated");
|
||||
ImGui::TableSetupColumn("Mitigation %");
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
DrawRow("Damage Per Second", Damage.Mitigated.DamagePerSecond, Damage.Unmitigated.DamagePerSecond, ImVec4(1.0f, 1.0, 0.0f, 1.0f));
|
||||
DrawRow("Damage Total", Damage.Mitigated.DamageTotal, Damage.Unmitigated.DamageTotal, ImVec4(1.0f, 1.0, 1.0f, 1.0f));
|
||||
DrawRow("Damage Last", Damage.Mitigated.DamageLast, Damage.Unmitigated.DamageLast, ImVec4(1.0f, 1.0, 1.0f, 1.0f));
|
||||
DrawRow("Damage Min", Damage.Mitigated.DamageMin, Damage.Unmitigated.DamageMin, ImVec4(1.0f, 1.0, 1.0f, 1.0f));
|
||||
DrawRow("Damage Min", Damage.Mitigated.DamageMax, Damage.Unmitigated.DamageMax, ImVec4(1.0f, 1.0, 1.0f, 1.0f));
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::Text("Crits");
|
||||
ImGui::SameLine(FCogWindowWidgets::TextBaseWidth * 20);
|
||||
FCogWindowWidgets::ProgressBarCentered(Damage.Count == 0 ? 0.0f : Damage.Crits / (float)Damage.Count, ImVec2(-1, 0), TCHAR_TO_ANSI(*FString::Printf(TEXT("%d / %d"), Damage.Crits, Damage.Count)));
|
||||
|
||||
if (FCogDamageStats::MaxDurationSetting > 0)
|
||||
{
|
||||
ImGui::Text("Timer");
|
||||
ImGui::SameLine(FCogWindowWidgets::TextBaseWidth * 20);
|
||||
FCogWindowWidgets::ProgressBarCentered(Damage.Timer / Damage.MaxDuration, ImVec2(-1, 0), TCHAR_TO_ANSI(*FString::Printf(TEXT("%0.1f / %0.1f"), Damage.Timer, Damage.MaxDuration)));
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
if (ImGui::Button("Restart"))
|
||||
{
|
||||
Damage.Restart();
|
||||
}
|
||||
|
||||
ImGui::PopStyleColor(5);
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::Spacing();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCogAbilityWindow_Damages::UCogAbilityWindow_Damages()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Damages::RenderContent()
|
||||
{
|
||||
Super::RenderContent();
|
||||
|
||||
AActor* Selection = GetSelection();
|
||||
if (Selection == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ImGui::CollapsingHeader("Damage Dealt"))
|
||||
{
|
||||
ImGui::PushID("Damage Dealt");
|
||||
DrawDamages(DamageDealtStats);
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
if (ImGui::CollapsingHeader("Damage Received"))
|
||||
{
|
||||
ImGui::PushID("Damage Received");
|
||||
DrawDamages(DamageReceivedStats);
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
if (ImGui::CollapsingHeader("Settings"))
|
||||
{
|
||||
ImGui::PushItemWidth(-1);
|
||||
|
||||
ImGui::Text("Auto Restart");
|
||||
ImGui::SameLine(FCogWindowWidgets::TextBaseWidth * 20);
|
||||
bool AutoRestart = FCogDamageStats::RestartDelaySetting > 0;
|
||||
if (ImGui::Checkbox("##Auto Restart", &AutoRestart))
|
||||
{
|
||||
FCogDamageStats::RestartDelaySetting = AutoRestart ? 5.0f : 0.0f;
|
||||
}
|
||||
|
||||
if (AutoRestart)
|
||||
{
|
||||
ImGui::Text("Auto Restart Delay");
|
||||
ImGui::SameLine(FCogWindowWidgets::TextBaseWidth * 20);
|
||||
ImGui::InputFloat("##Auto Restart Delay", &FCogDamageStats::RestartDelaySetting);
|
||||
}
|
||||
|
||||
ImGui::Text("Max Time");
|
||||
ImGui::SameLine(FCogWindowWidgets::TextBaseWidth * 20);
|
||||
if (ImGui::InputFloat("##Max Time", &FCogDamageStats::MaxDurationSetting, 0.0f, 0.0f, "%0.1f"))
|
||||
{
|
||||
DamageDealtStats.Restart();
|
||||
DamageReceivedStats.Restart();
|
||||
}
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Damages::OnSelectionChanged(AActor* OldSelection, AActor* NewSelection)
|
||||
{
|
||||
if (ICogAbilityDamageActorInterface* DamageActor = Cast<ICogAbilityDamageActorInterface>(OldSelection))
|
||||
{
|
||||
DamageActor->OnDamageEvent().Remove(OnDamageEventDelegate);
|
||||
}
|
||||
|
||||
if (ICogAbilityDamageActorInterface* DamageActor = Cast<ICogAbilityDamageActorInterface>(NewSelection))
|
||||
{
|
||||
OnDamageEventDelegate = DamageActor->OnDamageEvent().AddUObject(this, &UCogAbilityWindow_Damages::OnDamageEvent);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Damages::RenderTick(float DeltaSeconds)
|
||||
{
|
||||
Super::RenderTick(DeltaSeconds);
|
||||
|
||||
DamageReceivedStats.Tick(DeltaSeconds);
|
||||
DamageDealtStats.Tick(DeltaSeconds);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Damages::OnDamageEvent(const FCogAbilityDamageParams& Params)
|
||||
{
|
||||
DamageDealtStats.Restart();
|
||||
DamageReceivedStats.Restart();
|
||||
|
||||
AActor* Selection = GetSelection();
|
||||
if (Selection == Params.DamageDealer.Get())
|
||||
{
|
||||
DamageDealtStats.AddDamage(Params.ReceivedDamage, Params.IncomingDamage, Params.IsCritical);
|
||||
}
|
||||
else if (Selection == Params.DamageReceiver.Get())
|
||||
{
|
||||
DamageReceivedStats.AddDamage(Params.ReceivedDamage, Params.IncomingDamage, Params.IsCritical);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,343 @@
|
||||
#include "CogAbilityWindow_Effects.h"
|
||||
|
||||
#include "AbilitySystemComponent.h"
|
||||
#include "AbilitySystemGlobals.h"
|
||||
#include "AttributeSet.h"
|
||||
#include "CogAbilityHelper.h"
|
||||
#include "CogWindowWidgets.h"
|
||||
#include "EngineUtils.h"
|
||||
#include "GameFramework/Character.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Effects::PreRender(ImGuiWindowFlags& WindowFlags)
|
||||
{
|
||||
Super::PreRender(WindowFlags);
|
||||
|
||||
WindowFlags |= ImGuiWindowFlags_MenuBar;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Effects::RenderContent()
|
||||
{
|
||||
Super::RenderContent();
|
||||
|
||||
UAbilitySystemComponent* AbilitySystemComponent = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(GetSelection(), true);
|
||||
if (AbilitySystemComponent == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::BeginTable("Effects", 4, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_NoBordersInBodyUntilResize | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersH | ImGuiTableFlags_NoBordersInBody);
|
||||
ImGui::TableSetupColumn("Effect");
|
||||
ImGui::TableSetupColumn("Remaining Time");
|
||||
ImGui::TableSetupColumn("Stacks");
|
||||
ImGui::TableSetupColumn("Prediction");
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
static int SelectedIndex = -1;
|
||||
int Index = 0;
|
||||
|
||||
FGameplayEffectQuery Query;
|
||||
for (const FActiveGameplayEffectHandle& ActiveHandle : AbilitySystemComponent->GetActiveEffects(Query))
|
||||
{
|
||||
DrawEffectRow(*AbilitySystemComponent, ActiveHandle, Index, SelectedIndex);
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Effects::DrawEffectRow(const UAbilitySystemComponent& AbilitySystemComponent, const FActiveGameplayEffectHandle& ActiveHandle, int32 Index, int32& Selected)
|
||||
{
|
||||
ImGui::PushID(Index);
|
||||
|
||||
const FActiveGameplayEffect* ActiveEffectPtr = AbilitySystemComponent.GetActiveGameplayEffect(ActiveHandle);
|
||||
if (ActiveEffectPtr == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const UGameplayEffect* EffectPtr = ActiveEffectPtr->Spec.Def;
|
||||
if (EffectPtr == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const FActiveGameplayEffect& ActiveEffect = *ActiveEffectPtr;
|
||||
const UGameplayEffect& Effect = *EffectPtr;
|
||||
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_None, 0.0f);
|
||||
|
||||
//------------------------
|
||||
// Name
|
||||
//------------------------
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
const FGameplayTagContainer& Tags = Effect.InheritableGameplayEffectTags.CombinedTags;
|
||||
|
||||
ImVec4 Color;
|
||||
if (Tags.HasTag(NegativeEffectTag))
|
||||
{
|
||||
Color = ImVec4(1.0f, 0.5f, 0.5f, 1.0f);
|
||||
}
|
||||
else if (Tags.HasTag(PositiveEffectTag))
|
||||
{
|
||||
Color = ImVec4(0.5f, 1.0f, 0.5f, 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
Color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, Color);
|
||||
|
||||
if (ImGui::Selectable(TCHAR_TO_ANSI(*GetEffectName(Effect)), Selected == Index, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap | ImGuiSelectableFlags_AllowDoubleClick))
|
||||
{
|
||||
Selected = Index;
|
||||
}
|
||||
|
||||
ImGui::PopStyleColor(1);
|
||||
|
||||
//------------------------
|
||||
// Popup
|
||||
//------------------------
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
FCogWindowWidgets::BeginTableTooltip();
|
||||
DrawEffectInfo(AbilitySystemComponent, ActiveEffect, Effect);
|
||||
FCogWindowWidgets::EndTableTooltip();
|
||||
}
|
||||
|
||||
//------------------------
|
||||
// ContextMenu
|
||||
//------------------------
|
||||
if (ImGui::BeginPopupContextItem())
|
||||
{
|
||||
if (ImGui::Button("Open Properties"))
|
||||
{
|
||||
//GetOwner()->GetPropertyGrid()->Open(EffectPtr);
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
//------------------------
|
||||
// Remaining Time
|
||||
//------------------------
|
||||
ImGui::TableNextColumn();
|
||||
DrawRemainingTime(AbilitySystemComponent, ActiveEffect);
|
||||
|
||||
//------------------------
|
||||
// Stacks
|
||||
//------------------------
|
||||
ImGui::TableNextColumn();
|
||||
DrawStacks(ActiveEffect, Effect);
|
||||
|
||||
//------------------------
|
||||
// Prediction
|
||||
//------------------------
|
||||
ImGui::TableNextColumn();
|
||||
DrawPrediction(ActiveEffect, true);
|
||||
|
||||
ImGui::PopID();
|
||||
Index++;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Effects::DrawEffectInfo(const UAbilitySystemComponent& AbilitySystemComponent, const FActiveGameplayEffect& ActiveEffect, const UGameplayEffect& Effect)
|
||||
{
|
||||
if (ImGui::BeginTable("Effect", 2, ImGuiTableFlags_Borders))
|
||||
{
|
||||
const ImVec4 TextColor(1.0f, 1.0f, 1.0f, 0.5f);
|
||||
|
||||
ImGui::TableSetupColumn("Property");
|
||||
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
|
||||
|
||||
//------------------------
|
||||
// Name
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "Name");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", TCHAR_TO_ANSI(*GetEffectName(Effect)));
|
||||
|
||||
//------------------------
|
||||
// Level
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "Level");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%0.0f", ActiveEffect.Spec.GetLevel());
|
||||
|
||||
//------------------------
|
||||
// Remaining Time
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "Remaining Time");
|
||||
ImGui::TableNextColumn();
|
||||
DrawRemainingTime(AbilitySystemComponent, ActiveEffect);
|
||||
|
||||
//------------------------
|
||||
// Period
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "Period");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%0.3f", ActiveEffect.GetPeriod());
|
||||
|
||||
//------------------------
|
||||
// Stacks
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "Stacks");
|
||||
ImGui::TableNextColumn();
|
||||
DrawStacks(ActiveEffect, Effect);
|
||||
|
||||
//------------------------
|
||||
// Prediction
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "Prediction");
|
||||
ImGui::TableNextColumn();
|
||||
DrawPrediction(ActiveEffect, false);
|
||||
|
||||
//------------------------
|
||||
// Dynamic Asset Tags
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "Dynamic Asset Tags");
|
||||
ImGui::TableNextColumn();
|
||||
DrawTagContainer(ActiveEffect.Spec.GetDynamicAssetTags());
|
||||
|
||||
//------------------------
|
||||
// All Asset Tags
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "All Asset Tags");
|
||||
ImGui::TableNextColumn();
|
||||
FGameplayTagContainer AllAssetTagsContainer;
|
||||
ActiveEffect.Spec.GetAllAssetTags(AllAssetTagsContainer);
|
||||
DrawTagContainer(AllAssetTagsContainer);
|
||||
|
||||
//------------------------
|
||||
// All Granted Tags
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "All Granted Tags");
|
||||
ImGui::TableNextColumn();
|
||||
FGameplayTagContainer AllGrantedTagsContainer;
|
||||
ActiveEffect.Spec.GetAllGrantedTags(AllGrantedTagsContainer);
|
||||
DrawTagContainer(AllGrantedTagsContainer);
|
||||
|
||||
//------------------------
|
||||
// Modifiers
|
||||
//------------------------
|
||||
for (int32 i = 0; i < ActiveEffect.Spec.Modifiers.Num(); ++i)
|
||||
{
|
||||
const FModifierSpec& ModSpec = ActiveEffect.Spec.Modifiers[i];
|
||||
const FGameplayModifierInfo& ModInfo = ActiveEffect.Spec.Def->Modifiers[i];
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "Attribute Modifier");
|
||||
ImGui::TextColored(TextColor, "Operation");
|
||||
ImGui::TextColored(TextColor, "Magnitude");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", TCHAR_TO_ANSI(*ModInfo.Attribute.GetName()));
|
||||
ImGui::Text("%s", TCHAR_TO_ANSI(*EGameplayModOpToString(ModInfo.ModifierOp)));
|
||||
ImGui::Text("%0.2f", ModSpec.GetEvaluatedMagnitude());
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Effects::DrawTagContainer(const FGameplayTagContainer& Container)
|
||||
{
|
||||
TArray<FGameplayTag> GameplayTags;
|
||||
Container.GetGameplayTagArray(GameplayTags);
|
||||
for (FGameplayTag Tag : GameplayTags)
|
||||
{
|
||||
ImGui::Text("%s", TCHAR_TO_ANSI(*Tag.ToString()));
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
FString UCogAbilityWindow_Effects::GetEffectName(const UGameplayEffect& Effect)
|
||||
{
|
||||
FString Str = FCogAbilityHelper::CleanupName(Effect.GetName());
|
||||
return Str;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Effects::DrawRemainingTime(const UAbilitySystemComponent& AbilitySystemComponent, const FActiveGameplayEffect& ActiveEffect)
|
||||
{
|
||||
float StartTime = ActiveEffect.StartWorldTime;
|
||||
float Duration = ActiveEffect.GetDuration();
|
||||
|
||||
if (Duration <= 0)
|
||||
{
|
||||
ImGui::Text("NA");
|
||||
}
|
||||
else
|
||||
{
|
||||
UWorld* World = AbilitySystemComponent.GetWorld();
|
||||
const float RemainingTime = StartTime + Duration - World->GetTimeSeconds();
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, IM_COL32(100, 100, 100, 255));
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, IM_COL32(0, 0, 0, 100));
|
||||
ImGui::ProgressBar(RemainingTime / Duration, ImVec2(FCogWindowWidgets::TextBaseWidth * 15, FCogWindowWidgets::TextBaseHeight * 0.8f), TCHAR_TO_ANSI(*FString::Printf(TEXT("%.2f / %.2f"), RemainingTime, Duration)));
|
||||
ImGui::PopStyleColor(2);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Effects::DrawStacks(const FActiveGameplayEffect& ActiveEffect, const UGameplayEffect& Effect)
|
||||
{
|
||||
const int32 CurrentStackCount = ActiveEffect.Spec.StackCount;
|
||||
if (Effect.StackLimitCount <= 0)
|
||||
{
|
||||
ImGui::Text("0");
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, IM_COL32(100, 100, 100, 255));
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, IM_COL32(0, 0, 0, 100));
|
||||
ImGui::SetNextItemWidth(-1);
|
||||
ImGui::ProgressBar(CurrentStackCount / (float)Effect.StackLimitCount, ImVec2(FCogWindowWidgets::TextBaseWidth * 15, FCogWindowWidgets::TextBaseHeight * 0.8f), TCHAR_TO_ANSI(*FString::Printf(TEXT("%d / %d"), CurrentStackCount, Effect.StackLimitCount)));
|
||||
ImGui::PopStyleColor(2);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Effects::DrawPrediction(const FActiveGameplayEffect& ActiveEffect, bool Short)
|
||||
{
|
||||
FString PredictionString;
|
||||
if (ActiveEffect.PredictionKey.IsValidKey())
|
||||
{
|
||||
if (ActiveEffect.PredictionKey.WasLocallyGenerated())
|
||||
{
|
||||
PredictionString = Short ? FString("Wait") : FString("Predicted and Waiting");
|
||||
}
|
||||
else
|
||||
{
|
||||
PredictionString = Short ? FString("Done") : FString("Predicted and Caught Up");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PredictionString = Short ? FString("No") : FString("Not Predicted");
|
||||
}
|
||||
|
||||
ImGui::Text("%s", TCHAR_TO_ANSI(*PredictionString));
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
#include "CogAbilityWindow_Pools.h"
|
||||
|
||||
#include "AbilitySystemComponent.h"
|
||||
#include "CogImguiHelper.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCogAbilityWindow_Pools::UCogAbilityWindow_Pools()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void DrawPool(const UAbilitySystemComponent* AbilitySystemComponent, const FCogAbilityPool& Pool)
|
||||
{
|
||||
if (AbilitySystemComponent->HasAttributeSetForAttribute(Pool.Max) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (AbilitySystemComponent->HasAttributeSetForAttribute(Pool.Value) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", TCHAR_TO_ANSI(*Pool.Name));
|
||||
|
||||
const float Value = AbilitySystemComponent->GetNumericAttribute(Pool.Value);
|
||||
const float Max = AbilitySystemComponent->GetNumericAttribute(Pool.Max);
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
// Use a different format base on max value for all pools to be nicely aligned at the center
|
||||
//-------------------------------------------------------------------------------------------
|
||||
const char* format = nullptr;
|
||||
if (Max >= 100) { format = "%3.0f / %3.0f"; } // |200 / 200| |__1 / 200| 3 characters with 0 floating point
|
||||
else if (Max >= 10) { format = "%4.1f / %4.1f"; } // |20.0 / 20.0| |_1.1 / 20.0| 4 characters with 1 floating point
|
||||
else { format = "%3.2f / %3.2f"; } // |2.00 / 2.00| |1.11 / 2.00| 3 characters with 2 floating points
|
||||
|
||||
char Buffer[64];
|
||||
ImFormatString(Buffer, IM_ARRAYSIZE(Buffer), format, Value, Max);
|
||||
|
||||
const float Ratio = Max > 0.0f ? Value / Max : 0.0f;
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, FCogImguiHelper::ToImVec4(Pool.Color));
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, FCogImguiHelper::ToImVec4(Pool.BackColor));
|
||||
FCogWindowWidgets::ProgressBarCentered(Ratio, ImVec2(-1, 0), Buffer);
|
||||
ImGui::PopStyleColor(2);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Pools::RenderContent()
|
||||
{
|
||||
Super::RenderContent();
|
||||
|
||||
if (PoolsAsset == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UAbilitySystemComponent* AbilitySystem = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(GetSelection(), true);
|
||||
if (AbilitySystem == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ImGui::BeginTable("Pools", 2, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_NoBordersInBodyUntilResize))
|
||||
{
|
||||
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableSetupColumn("Pool", ImGuiTableColumnFlags_WidthStretch);
|
||||
|
||||
for (const FCogAbilityPool& Pool : PoolsAsset->Pools)
|
||||
{
|
||||
DrawPool(AbilitySystem, Pool);
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
#include "CogAbilityWindow_Tags.h"
|
||||
|
||||
#include "AbilitySystemComponent.h"
|
||||
#include "CogAbilityHelper.h"
|
||||
#include "CogWindowWidgets.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
static void DrawTagInfo(const UAbilitySystemComponent& AbilitySystemComponent, const FGameplayTag& Tag)
|
||||
{
|
||||
if (ImGui::BeginTable("Tag", 2, ImGuiTableFlags_Borders))
|
||||
{
|
||||
const ImVec4 TextColor(1.0f, 1.0f, 1.0f, 0.5f);
|
||||
|
||||
ImGui::TableSetupColumn("Property");
|
||||
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
|
||||
|
||||
//------------------------
|
||||
// Name
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "Name");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", TCHAR_TO_ANSI(*Tag.GetTagName().ToString()));
|
||||
|
||||
//------------------------
|
||||
// Base Value
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "Count");
|
||||
ImGui::TableNextColumn();
|
||||
const int32 TagCount = AbilitySystemComponent.GetTagCount(Tag);
|
||||
ImGui::TextColored(TagCount > 1 ? ImVec4(1.0f, 1.0f, 0.0f, 1.0f) : ImVec4(1.0f, 1.0f, 1.0f, 1.0f), "%d", TagCount);
|
||||
|
||||
//------------------------
|
||||
// Abilities
|
||||
//------------------------
|
||||
//ImGui::TableNextRow();
|
||||
//ImGui::TableNextColumn();
|
||||
//ImGui::TextColored(TextColor, "Abilities");
|
||||
//ImGui::TableNextColumn();
|
||||
//for (FGameplayAbilitySpec AbilitySpec : AbilitySystemComponent.GetActivatableAbilities())
|
||||
//{
|
||||
// UGameplayAbility* Ability = AbilitySpec.GetPrimaryInstance() != nullptr ? AbilitySpec.GetPrimaryInstance() : AbilitySpec.Ability;
|
||||
// if (Ability == nullptr)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// if (Ability->ActivationOwnedTags GetActivationOwnedTags().HasTagExact(Tag))
|
||||
// {
|
||||
// ImGui::Text("%s", TCHAR_TO_ANSI(*FCogAbilityHelper::CleanupName(GetNameSafe(Ability))));
|
||||
// }
|
||||
//}
|
||||
|
||||
//------------------------
|
||||
// Effects
|
||||
//------------------------
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(TextColor, "Effects");
|
||||
ImGui::TableNextColumn();
|
||||
FGameplayEffectQuery Query;
|
||||
for (const FActiveGameplayEffectHandle& ActiveHandle : AbilitySystemComponent.GetActiveEffects(Query))
|
||||
{
|
||||
const FActiveGameplayEffect* ActiveEffect = AbilitySystemComponent.GetActiveGameplayEffect(ActiveHandle);
|
||||
if (ActiveEffect == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
FGameplayTagContainer Container;
|
||||
ActiveEffect->Spec.GetAllGrantedTags(Container);
|
||||
|
||||
if (Container.HasTagExact(Tag))
|
||||
{
|
||||
ImGui::Text("%s", TCHAR_TO_ANSI(*FCogAbilityHelper::CleanupName(GetNameSafe(ActiveEffect->Spec.Def))));
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
static void DrawTags(const FString& Title, UAbilitySystemComponent& AbilitySystemComponent, FGameplayTagContainer& TagContainer)
|
||||
{
|
||||
if (ImGui::BeginTable(TCHAR_TO_ANSI(*Title), 2, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_NoBordersInBodyUntilResize | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_BordersOuterV))
|
||||
{
|
||||
ImGui::TableSetupColumn("Count");
|
||||
ImGui::TableSetupColumn(TCHAR_TO_ANSI(*Title));
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
TArray<FGameplayTag> Tags;
|
||||
TagContainer.GetGameplayTagArray(Tags);
|
||||
|
||||
static int Selected = -1;
|
||||
int index = 0;
|
||||
|
||||
for (const FGameplayTag& Tag : Tags)
|
||||
{
|
||||
ImGui::TableNextRow();
|
||||
|
||||
ImGui::PushID(index);
|
||||
|
||||
//------------------------
|
||||
// Count
|
||||
//------------------------
|
||||
ImGui::TableNextColumn();
|
||||
const int32 TagCount = AbilitySystemComponent.GetTagCount(Tag);
|
||||
ImGui::TextColored(TagCount > 1 ? ImVec4(1.0f, 1.0f, 0.0f, 1.0f) : ImVec4(1.0f, 1.0f, 1.0f, 1.0f), "%d", TagCount);
|
||||
|
||||
//------------------------
|
||||
// Name
|
||||
//------------------------
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Selectable(TCHAR_TO_ANSI(*Tag.GetTagName().ToString()), Selected == index, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap | ImGuiSelectableFlags_AllowDoubleClick))
|
||||
{
|
||||
Selected = index;
|
||||
}
|
||||
|
||||
//------------------------
|
||||
// Popup
|
||||
//------------------------
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
FCogWindowWidgets::BeginTableTooltip();
|
||||
DrawTagInfo(AbilitySystemComponent, Tag);
|
||||
FCogWindowWidgets::EndTableTooltip();
|
||||
}
|
||||
|
||||
|
||||
ImGui::PopID();
|
||||
index++;
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
UCogAbilityWindow_Tags::UCogAbilityWindow_Tags()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Tags::PreRender(ImGuiWindowFlags& WindowFlags)
|
||||
{
|
||||
WindowFlags = ImGuiWindowFlags_MenuBar;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Tags::RenderContent()
|
||||
{
|
||||
Super::RenderContent();
|
||||
|
||||
UAbilitySystemComponent* AbilitySystemComponent = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(GetSelection(), true);
|
||||
if (AbilitySystemComponent == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FGameplayTagContainer OwnedTags, BlockedTags;
|
||||
AbilitySystemComponent->GetOwnedGameplayTags(OwnedTags);
|
||||
AbilitySystemComponent->GetBlockedAbilityTags(BlockedTags);
|
||||
|
||||
DrawTags("Owned Tags", *AbilitySystemComponent, OwnedTags);
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
#include "CogAbilityWindow_Tweaks.h"
|
||||
|
||||
#include "AbilitySystemComponent.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCogAbilityWindow_Tweaks::UCogAbilityWindow_Tweaks()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void DrawTweak(ACogAbilityReplicator* Replicator, const UCogAbilityDataAsset_Tweaks* TweaksAsset, int32 TweakIndex, int32 TweakCategoryIndex)
|
||||
{
|
||||
if (TweaksAsset->TweaksCategories.IsValidIndex(TweakCategoryIndex) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float* Value = Replicator->GetTweakCurrentValuePtr(TweaksAsset, TweakIndex, TweakCategoryIndex);
|
||||
if (Value == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const FCogAbilityTweakCategory& Category = TweaksAsset->TweaksCategories[TweakCategoryIndex];
|
||||
const FLinearColor& Color = Category.Color;
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(Color.R, Color.G, Color.B, Color.A * 0.25f));
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(Color.R, Color.G, Color.B, Color.A * 0.3f));
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(Color.R, Color.G, Color.B, Color.A * 0.5f));
|
||||
ImGui::PushStyleColor(ImGuiCol_SliderGrab, ImVec4(Color.R, Color.G, Color.B, Color.A * 0.8f));
|
||||
ImGui::PushStyleColor(ImGuiCol_SliderGrabActive, ImVec4(Color.R, Color.G, Color.B, Color.A * 1.0f));
|
||||
|
||||
|
||||
ImGui::PushItemWidth(-1);
|
||||
ImGui::SliderFloat("##Value", Value, TweaksAsset->TweakMinValue, TweaksAsset->TweakMaxValue, "%+0.0f%%", 1.0f);
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
ImGui::PopStyleColor(5);
|
||||
|
||||
bool bUpdateValue = ImGui::IsItemDeactivatedAfterEdit();
|
||||
|
||||
if (ImGui::BeginPopupContextItem())
|
||||
{
|
||||
if (ImGui::Button("Reset"))
|
||||
{
|
||||
*Value = 0.f;
|
||||
bUpdateValue = true;
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
if (bUpdateValue)
|
||||
{
|
||||
Replicator->SetTweakValue(TweaksAsset, TweakIndex, TweakCategoryIndex, *Value);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogAbilityWindow_Tweaks::RenderContent()
|
||||
{
|
||||
Super::RenderContent();
|
||||
|
||||
FCogAbilityModule& Module = FCogAbilityModule::Get();
|
||||
ACogAbilityReplicator* Replicator = Module.GetLocalReplicator();
|
||||
if (Replicator == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
if (ImGui::MenuItem("Reset"))
|
||||
{
|
||||
Replicator->ResetAllTweaks();
|
||||
}
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
int32 CurrentTweakProfileIndex = Replicator->GetTweakProfileIndex();
|
||||
FName CurrentProfileName = FName("None");
|
||||
if (TweaksAsset->TweakProfiles.IsValidIndex(CurrentTweakProfileIndex))
|
||||
{
|
||||
CurrentProfileName = TweaksAsset->TweakProfiles[CurrentTweakProfileIndex].Name;
|
||||
}
|
||||
|
||||
if (ImGui::BeginCombo("Profile", TCHAR_TO_ANSI(*CurrentProfileName.ToString())))
|
||||
{
|
||||
{
|
||||
bool IsSelected = CurrentTweakProfileIndex == INDEX_NONE;
|
||||
if (ImGui::Selectable("None", IsSelected))
|
||||
{
|
||||
Replicator->SetTweakProfile(TweaksAsset.Get(), INDEX_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
for (int32 TweakProfileIndex = 0; TweakProfileIndex < TweaksAsset->TweakProfiles.Num(); ++TweakProfileIndex)
|
||||
{
|
||||
const FCogAbilityTweakProfile& TweakProfile = TweaksAsset->TweakProfiles[TweakProfileIndex];
|
||||
bool IsSelected = TweakProfileIndex == CurrentTweakProfileIndex;
|
||||
|
||||
if (ImGui::Selectable(TCHAR_TO_ANSI(*TweakProfile.Name.ToString()), IsSelected))
|
||||
{
|
||||
Replicator->SetTweakProfile(TweaksAsset.Get(), TweakProfileIndex);
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::BeginTable("Tweaks", 1 + TweaksAsset->TweaksCategories.Num(), ImGuiTableFlags_Resizable | ImGuiTableFlags_NoBordersInBodyUntilResize))
|
||||
{
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch);
|
||||
for (int32 TweakCategoryIndex = 0; TweakCategoryIndex < TweaksAsset->TweaksCategories.Num(); ++TweakCategoryIndex)
|
||||
{
|
||||
FCogAbilityTweakCategory& Category = TweaksAsset->TweaksCategories[TweakCategoryIndex];
|
||||
ImGui::TableSetupColumn(TCHAR_TO_ANSI(*Category.Name), ImGuiTableColumnFlags_WidthStretch);
|
||||
}
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
ImGui::TableNextRow();
|
||||
|
||||
int32 TweakIndex = 0;
|
||||
for (FCogAbilityTweak& Tweak : TweaksAsset->Tweaks)
|
||||
{
|
||||
if (Tweak.Effect != nullptr)
|
||||
{
|
||||
ImGui::PushID(TweakIndex);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", TCHAR_TO_ANSI(*Tweak.Name.ToString()));
|
||||
|
||||
for (int TweakCategoryIndex = 0; TweakCategoryIndex < TweaksAsset->TweaksCategories.Num(); ++TweakCategoryIndex)
|
||||
{
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::PushID(TweakCategoryIndex);
|
||||
DrawTweak(Replicator, TweaksAsset.Get(), TweakIndex, TweakCategoryIndex);
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
TweakIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogAbilityDamageActorInterface.generated.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
USTRUCT()
|
||||
struct COGABILITY_API FCogAbilityDamageParams
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
TObjectPtr<AActor> DamageDealer;
|
||||
TObjectPtr<AActor> DamageReceiver;
|
||||
float ReceivedDamage = 0;
|
||||
float IncomingDamage = 0;
|
||||
bool IsCritical = false;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
DECLARE_MULTICAST_DELEGATE_OneParam(FCogAbilityOnDamageEvent, const FCogAbilityDamageParams&);
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UINTERFACE(MinimalAPI, Blueprintable)
|
||||
class UCogAbilityDamageActorInterface : public UInterface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
class ICogAbilityDamageActorInterface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
virtual FCogAbilityOnDamageEvent& OnDamageEvent() = 0;
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataAsset.h"
|
||||
#include "CogAbilityDataAsset_Abilities.generated.h"
|
||||
|
||||
class UGameplayAbility;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCLASS(Blueprintable)
|
||||
class COGABILITY_API UCogAbilityDataAsset_Abilities : public UPrimaryDataAsset
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UCogAbilityDataAsset_Abilities() {}
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
TArray<TSubclassOf<UGameplayAbility>> Abilities;
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataAsset.h"
|
||||
#include "GameplayEffect.h"
|
||||
#include "CogAbilityDataAsset_Cheats.generated.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
USTRUCT()
|
||||
struct COGABILITY_API FCogAbilityCheat
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FString Name;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
TSubclassOf<UGameplayEffect> Effect;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCLASS(Blueprintable)
|
||||
class COGABILITY_API UCogAbilityDataAsset_Cheats : public UPrimaryDataAsset
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UCogAbilityDataAsset_Cheats() {}
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FGameplayTag NegativeEffectTag;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FGameplayTag PositiveEffectTag;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FLinearColor NeutralEffectColor = FLinearColor(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FLinearColor NegativeEffectColor = FLinearColor(1.0f, 0.5f, 0.5f, 1.0f);
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FLinearColor PositiveEffectColor = FLinearColor(0.0f, 1.0f, 0.5f, 1.0f);
|
||||
|
||||
UPROPERTY(EditAnywhere, meta = (TitleProperty = "Name"))
|
||||
TArray<FCogAbilityCheat> PersistentEffects;
|
||||
|
||||
UPROPERTY(EditAnywhere, meta = (TitleProperty = "Name"))
|
||||
TArray<FCogAbilityCheat> InstantEffects;
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataAsset.h"
|
||||
#include "CogAbilityDataAsset_Pools.generated.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
USTRUCT()
|
||||
struct COGABILITY_API FCogAbilityPool
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FString Name;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FGameplayAttribute Value;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FGameplayAttribute Min;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FGameplayAttribute Max;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FGameplayAttribute Regen;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FLinearColor Color = FLinearColor(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FLinearColor BackColor = FLinearColor(0.15, 0.15, 0.15, 1.0f);
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCLASS(Blueprintable)
|
||||
class COGABILITY_API UCogAbilityDataAsset_Pools : public UPrimaryDataAsset
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UCogAbilityDataAsset_Pools() {}
|
||||
|
||||
UPROPERTY(EditAnywhere, meta = (TitleProperty = "Name"))
|
||||
TArray<FCogAbilityPool> Pools;
|
||||
};
|
||||
@@ -0,0 +1,108 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataAsset.h"
|
||||
#include "CogAbilityDataAsset_Tweaks.generated.h"
|
||||
|
||||
class UGameplayEffect;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
USTRUCT()
|
||||
struct FCogAbilityTweak
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FName Name;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
TSubclassOf<UGameplayEffect> Effect;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
float Multiplier = 0.01f;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
float AddPostMultiplier = 1.0f;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
USTRUCT()
|
||||
struct FCogAbilityTweakCategory
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FString Name;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FGameplayTag Id;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
TSubclassOf<AActor> ActorClass;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FGameplayTagContainer RequiredTags;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FGameplayTagContainer IgnoredTags;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FLinearColor Color = FLinearColor::White;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
USTRUCT()
|
||||
struct FCogAbilityTweakProfileValue
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
TSubclassOf<UGameplayEffect> Effect;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FGameplayTag CategoryId;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
float Value = 0.0f;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
USTRUCT()
|
||||
struct FCogAbilityTweakProfile
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FName Name;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
TArray<FCogAbilityTweakProfileValue> Tweaks;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCLASS(Blueprintable)
|
||||
class COGABILITY_API UCogAbilityDataAsset_Tweaks : public UPrimaryDataAsset
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCogAbilityDataAsset_Tweaks() {}
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
float TweakMinValue = -100.0f;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
float TweakMaxValue = 200.0f;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
FGameplayTag SetByCallerMagnitudeTag;
|
||||
|
||||
UPROPERTY(EditAnywhere, meta = (TitleProperty = "Name"))
|
||||
TArray<FCogAbilityTweak> Tweaks;
|
||||
|
||||
UPROPERTY(EditAnywhere, meta = (TitleProperty = "Name"))
|
||||
TArray<FCogAbilityTweakCategory> TweaksCategories;
|
||||
|
||||
UPROPERTY(EditAnywhere, meta = (TitleProperty = "Name"))
|
||||
TArray<FCogAbilityTweakProfile> TweakProfiles;
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
|
||||
class COGABILITY_API FCogAbilityHelper
|
||||
{
|
||||
public:
|
||||
|
||||
static FString CleanupName(FString Str);
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
class ACogAbilityReplicator;
|
||||
class APlayerController;
|
||||
|
||||
class COGABILITY_API FCogAbilityModule : public IModuleInterface
|
||||
{
|
||||
public:
|
||||
|
||||
static inline FCogAbilityModule& Get()
|
||||
{
|
||||
return FModuleManager::LoadModuleChecked<FCogAbilityModule>("CogAbility");
|
||||
}
|
||||
|
||||
/** IModuleInterface implementation */
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
|
||||
ACogAbilityReplicator* GetLocalReplicator();
|
||||
void SetLocalReplicator(ACogAbilityReplicator* Value);
|
||||
ACogAbilityReplicator* GetRemoteReplicator(const APlayerController* PlayerController);
|
||||
void AddRemoteReplicator(ACogAbilityReplicator* Value);
|
||||
|
||||
private:
|
||||
TObjectPtr<ACogAbilityReplicator> LocalReplicator;
|
||||
TArray<TObjectPtr<ACogAbilityReplicator>> RemoteReplicators;
|
||||
};
|
||||
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "CogAbilityReplicator.generated.h"
|
||||
|
||||
class AActor;
|
||||
class UAbilitySystemComponent;
|
||||
class UCogAbilityDataAsset_Tweaks;
|
||||
struct FCogAbilityCheat;
|
||||
struct FCogAbilityTweak;
|
||||
struct FGameplayTag;
|
||||
|
||||
UCLASS(NotBlueprintable, NotBlueprintType, notplaceable, noteditinlinenew, hidedropdown, Transient)
|
||||
class COGABILITY_API ACogAbilityReplicator : public AActor
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
public:
|
||||
|
||||
static void Create(APlayerController* Controller);
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
APlayerController* GetPlayerController() const { return OwnerPlayerController.Get(); }
|
||||
|
||||
void ApplyCheat(AActor* CheatInstigator, const TArray<AActor*>& Targets, const FCogAbilityCheat& Cheat);
|
||||
|
||||
static bool IsCheatActive(const AActor* EffectTarget, const FCogAbilityCheat& Cheat);
|
||||
|
||||
void GiveAbility(AActor* TargetActor, TSubclassOf<UGameplayAbility> AbilityClass);
|
||||
|
||||
void ResetAllTweaks();
|
||||
|
||||
void SetTweakValue(const UCogAbilityDataAsset_Tweaks* TweaksAsset, int32 TweakIndex, int32 CategoryIndex, float Value);
|
||||
|
||||
void SetTweakProfile(const UCogAbilityDataAsset_Tweaks* TweaksAsset, int32 ProfileIndex);
|
||||
|
||||
int32 GetTweakProfileIndex() const { return TweakProfileIndex; }
|
||||
|
||||
float GetTweakCurrentValue(const UCogAbilityDataAsset_Tweaks* TweaksAsset, int32 TweakIndex, int32 CategoryIndex);
|
||||
|
||||
float* GetTweakCurrentValuePtr(const UCogAbilityDataAsset_Tweaks* TweaksAsset, int32 TweakIndex, int32 CategoryIndex);
|
||||
|
||||
private:
|
||||
|
||||
UFUNCTION(Reliable, Server)
|
||||
void Server_ApplyCheat(const AActor* CheatInstigator, const TArray<AActor*>& TargetActors, const FCogAbilityCheat& Cheat) const;
|
||||
|
||||
UFUNCTION(Reliable, Server)
|
||||
void Server_GiveAbility(AActor* TargetActor, TSubclassOf<UGameplayAbility> AbilityClass) const;
|
||||
|
||||
UFUNCTION(Reliable, Server)
|
||||
void Server_ResetAllTweaks();
|
||||
|
||||
UFUNCTION(Reliable, Server)
|
||||
void Server_SetTweakValue(const UCogAbilityDataAsset_Tweaks* TweaksAsset, int32 TweakIndex, int32 TweakCategoryIndex, float Value);
|
||||
|
||||
UFUNCTION(Reliable, Server)
|
||||
void Server_SetTweakProfile(const UCogAbilityDataAsset_Tweaks* TweaksAsset, int32 ProfileIndex);
|
||||
|
||||
void SetTweakCurrentValue(const UCogAbilityDataAsset_Tweaks* TweaksAsset, int32 TweakIndex, int32 CategoryIndex, float Value);
|
||||
void ApplyTweakOnActor(AActor* Actor, const FCogAbilityTweak& Tweak, float Value, const FGameplayTag& SetByCallerMagnitudeTag);
|
||||
void ApplyAllTweaksOnActor(const UCogAbilityDataAsset_Tweaks* TweaksAsset, int32 TweakCategoryIndex, AActor* Actor);
|
||||
void GetActorsFromTweakCategory(const UCogAbilityDataAsset_Tweaks* TweaksAsset, int32 CategoryIndex, TArray<AActor*>& Actors);
|
||||
|
||||
TObjectPtr<APlayerController> OwnerPlayerController;
|
||||
|
||||
UPROPERTY(Replicated)
|
||||
int32 TweakProfileIndex = INDEX_NONE;
|
||||
|
||||
UPROPERTY(Replicated)
|
||||
TArray<float> TweakCurrentValues;
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogWindow.h"
|
||||
#include "CogAbilityWindow_Abilities.generated.h"
|
||||
|
||||
class UGameplayAbility;
|
||||
class UCogAbilityDataAsset_Abilities;
|
||||
struct FGameplayAbilitySpec;
|
||||
|
||||
UCLASS()
|
||||
class COGABILITY_API UCogAbilityWindow_Abilities : public UCogWindow
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
TWeakObjectPtr<UCogAbilityDataAsset_Abilities> AbilitiesAsset;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void PreRender(ImGuiWindowFlags& WindowFlags) override;
|
||||
|
||||
virtual void RenderTick(float DetlaTime) override;
|
||||
|
||||
virtual void RenderContent() override;
|
||||
|
||||
virtual void GameTick(float DeltaTime) override;
|
||||
|
||||
virtual void RenderAbiltiesMenu(AActor* Selection);
|
||||
|
||||
virtual FString GetAbilityName(const UGameplayAbility* Ability);
|
||||
|
||||
virtual void RenderAbilitiesTable(UAbilitySystemComponent& AbilitySystemComponent);
|
||||
|
||||
virtual void RenderAbilityContextMenu(UAbilitySystemComponent& AbilitySystemComponent, FGameplayAbilitySpec& Spec, int Index);
|
||||
|
||||
virtual void RenderOpenAbilities();
|
||||
|
||||
virtual void RenderAbilityInfo(FGameplayAbilitySpec& Spec);
|
||||
|
||||
virtual void ProcessAbilityActivation(FGameplayAbilitySpecHandle Handle);
|
||||
|
||||
virtual void ActivateAbility(UAbilitySystemComponent& AbilitySystemComponent, FGameplayAbilitySpec& Spec);
|
||||
|
||||
virtual void DeactivateAbility(UAbilitySystemComponent& AbilitySystemComponent, FGameplayAbilitySpec& Spec);
|
||||
|
||||
virtual void OpenAbility(FGameplayAbilitySpecHandle Handle);
|
||||
|
||||
virtual void CloseAbility(FGameplayAbilitySpecHandle Handle);
|
||||
|
||||
private:
|
||||
|
||||
FGameplayAbilitySpecHandle AbilityHandleToActivate;
|
||||
|
||||
TArray<FGameplayAbilitySpecHandle> OpenedAbilities;
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogWindow.h"
|
||||
#include "CogAbilityWindow_Attributes.generated.h"
|
||||
|
||||
UCLASS(Config = Cog)
|
||||
class COGABILITY_API UCogAbilityWindow_Attributes : public UCogWindow
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCogAbilityWindow_Attributes();
|
||||
|
||||
virtual void PreRender(ImGuiWindowFlags& WindowFlags) override;
|
||||
virtual void RenderContent() override;
|
||||
|
||||
UPROPERTY(Config)
|
||||
bool bSortByNameSetting = true;
|
||||
|
||||
UPROPERTY(Config)
|
||||
bool bGroupByAttributeSetSetting = false;
|
||||
|
||||
UPROPERTY(Config)
|
||||
bool bGroupByCategorySetting = false;
|
||||
|
||||
UPROPERTY(Config)
|
||||
bool bShowOnlyModified = false;
|
||||
|
||||
ImGuiTextFilter Filter;
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogWindow.h"
|
||||
#include "CogAbilityWindow_Cheats.generated.h"
|
||||
|
||||
class AActor;
|
||||
class UCogAbilityDataAsset_Cheats;
|
||||
struct FCogAbilityCheat;
|
||||
|
||||
UCLASS(Config = Cog)
|
||||
class COGABILITY_API UCogAbilityWindow_Cheats : public UCogWindow
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCogAbilityWindow_Cheats();
|
||||
virtual void RenderContent() override;
|
||||
|
||||
TWeakObjectPtr<UCogAbilityDataAsset_Cheats> CheatsAsset;
|
||||
|
||||
private:
|
||||
|
||||
void AddCheat(AActor* InstigatorActor, AActor* TargetActor, const FCogAbilityCheat& CheatEffect, bool IsPersistent);
|
||||
|
||||
void RequestCheat(AActor* InstigatorActor, AActor* TargetActor, const FCogAbilityCheat& CheatEffect);
|
||||
|
||||
UPROPERTY(Config)
|
||||
TArray<FString> AppliedCheats;
|
||||
};
|
||||
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogWindow.h"
|
||||
#include "CogAbilityWindow_Damages.generated.h"
|
||||
|
||||
struct FCogAbilityDamageParams;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
class FCogDamageInstance
|
||||
{
|
||||
public:
|
||||
void Restart();
|
||||
void AddDamage(const float Damage);
|
||||
void UpdateDamagePerSecond(const float Duration);
|
||||
|
||||
float DamageLast = 0.0f;
|
||||
float DamageMin = 0.0f;
|
||||
float DamageMax = 0.0f;
|
||||
float DamagePerFrame = 0.0f;
|
||||
float DamagePerSecond = 0.0f;
|
||||
float DamageTotal = 0.0f;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
class FCogDamageStats
|
||||
{
|
||||
public:
|
||||
void AddDamage(const float Damage, const float UnmitigatedDamage, const bool bIsCrit);
|
||||
void Tick(const float DeltaSeconds);
|
||||
void Restart();
|
||||
|
||||
int Count = 0;
|
||||
int Crits = 0;
|
||||
bool IsInProgress = false;
|
||||
float TotalCritChances = 0.0f;
|
||||
float Timer = 0.0f;
|
||||
float MaxDuration = 0.0f;
|
||||
float RestartTimer = 0.0f;
|
||||
|
||||
FCogDamageInstance Mitigated;
|
||||
FCogDamageInstance Unmitigated;
|
||||
|
||||
static float MaxDurationSetting;
|
||||
static float RestartDelaySetting;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCLASS()
|
||||
class COGABILITY_API UCogAbilityWindow_Damages : public UCogWindow
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCogAbilityWindow_Damages();
|
||||
virtual void RenderContent() override;
|
||||
virtual void RenderTick(float DeltaSeconds) override;
|
||||
|
||||
protected:
|
||||
virtual void OnSelectionChanged(AActor* OldSelection, AActor* NewSelection) override;
|
||||
|
||||
private:
|
||||
|
||||
UFUNCTION()
|
||||
void OnDamageEvent(const FCogAbilityDamageParams& Params);
|
||||
|
||||
FCogDamageStats DamageDealtStats;
|
||||
FCogDamageStats DamageReceivedStats;
|
||||
FDelegateHandle OnDamageEventDelegate;
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "CogWindow.h"
|
||||
#include "CogAbilityWindow_Effects.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class COGABILITY_API UCogAbilityWindow_Effects : public UCogWindow
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
FGameplayTag NegativeEffectTag;
|
||||
|
||||
FGameplayTag PositiveEffectTag;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void PreRender(ImGuiWindowFlags& WindowFlags) override;
|
||||
|
||||
virtual void RenderContent() override;
|
||||
|
||||
virtual void DrawEffectRow(const UAbilitySystemComponent& AbilitySystemComponent, const FActiveGameplayEffectHandle& ActiveHandle, int32 Index, int32& Selected);
|
||||
|
||||
virtual void DrawEffectInfo(const UAbilitySystemComponent& AbilitySystemComponent, const FActiveGameplayEffect& ActiveEffect, const UGameplayEffect& Effect);
|
||||
|
||||
virtual void DrawTagContainer(const FGameplayTagContainer& Container);
|
||||
|
||||
virtual FString GetEffectName(const UGameplayEffect& Effect);
|
||||
|
||||
virtual void DrawRemainingTime(const UAbilitySystemComponent& AbilitySystemComponent, const FActiveGameplayEffect& ActiveEffect);
|
||||
|
||||
virtual void DrawStacks(const FActiveGameplayEffect& ActiveEffect, const UGameplayEffect& Effect);
|
||||
|
||||
virtual void DrawPrediction(const FActiveGameplayEffect& ActiveEffect, bool Short);
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "CogWindow.h"
|
||||
#include "CogAbilityWindow_Pools.generated.h"
|
||||
|
||||
class UCogAbilityDataAsset_Pools;
|
||||
|
||||
UCLASS()
|
||||
class COGABILITY_API UCogAbilityWindow_Pools : public UCogWindow
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCogAbilityWindow_Pools();
|
||||
virtual void RenderContent() override;
|
||||
|
||||
TWeakObjectPtr<UCogAbilityDataAsset_Pools> PoolsAsset;
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogWindow.h"
|
||||
#include "CogAbilityWindow_Tags.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class COGABILITY_API UCogAbilityWindow_Tags : public UCogWindow
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCogAbilityWindow_Tags();
|
||||
|
||||
virtual void PreRender(ImGuiWindowFlags& WindowFlags) override;
|
||||
virtual void RenderContent() override;
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogWindow.h"
|
||||
#include "CogAbilityWindow_Tweaks.generated.h"
|
||||
|
||||
class AActor;
|
||||
class UCogAbilityDataAsset_Tweaks;
|
||||
class ACogAbilityReplicator;
|
||||
|
||||
UCLASS()
|
||||
class COGABILITY_API UCogAbilityWindow_Tweaks : public UCogWindow
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCogAbilityWindow_Tweaks();
|
||||
virtual void RenderContent() override;
|
||||
|
||||
TWeakObjectPtr<UCogAbilityDataAsset_Tweaks> TweaksAsset;
|
||||
|
||||
private:
|
||||
};
|
||||
Reference in New Issue
Block a user