First Submit

This commit is contained in:
Arnaud Jamin
2023-10-02 01:32:41 -04:00
parent c34574e841
commit 1aabdb5c4e
445 changed files with 93851 additions and 0 deletions
@@ -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:
};