CogEngine: Make the Cheat Execution implementable in blueprint

- Deprecate CogAbilityWindow_Cheats as it is now replaced with CogEngineWindow_Cheats
- Add CogAbilityCheat_Execution_ActivateAbility for cheats that rely on an ability
- CogSample: Add new cheats
This commit is contained in:
Arnaud Jamin
2025-02-04 21:52:53 -05:00
parent 27c309ad87
commit 74dd726c2c
20 changed files with 237 additions and 426 deletions
Binary file not shown.
Binary file not shown.
+2
View File
@@ -1,2 +1,4 @@
[CoreRedirects]
+StructRedirects=(OldName="/Script/CogDebug.CogLogCategory",NewName="/Script/CogCommon.CogLogCategory")
+PropertyRedirects=(OldName="/Script/CogEngine.CogEngineCheatCategory.PersistentEffects",NewName="/Script/CogEngine.CogEngineCheatCategory.PersistentCheats")
+PropertyRedirects=(OldName="/Script/CogEngine.CogEngineCheatCategory.InstantEffects",NewName="/Script/CogEngine.CogEngineCheatCategory.InstantCheats")
@@ -1,12 +1,12 @@
#include "CogEngineDataAsset.h"
//--------------------------------------------------------------------------------------------------------------------------
void UCogEngineCheat_Execution::Execute_Implementation(const AActor* Instigator, const TArray<AActor*>& Targets) const
void UCogEngineCheat_Execution::Execute_Implementation(const UObject* WorldContextObject, const AActor* Instigator, const TArray<AActor*>& Targets) const
{
}
//--------------------------------------------------------------------------------------------------------------------------
ECogEngineCheat_ActiveState UCogEngineCheat_Execution::IsActiveOnTargets_Implementation(const TArray<AActor*>& Targets) const
ECogEngineCheat_ActiveState UCogEngineCheat_Execution::IsActiveOnTargets_Implementation(const UObject* WorldContextObject, const TArray<AActor*>& Targets) const
{
return ECogEngineCheat_ActiveState::Inactive;
}
@@ -230,16 +230,16 @@ void ACogEngineReplicator::Server_ApplyCheat_Implementation(const AActor* CheatI
return;
}
Cheat.Execution->Execute(CheatInstigator, Targets);
Cheat.Execution->Execute(GetWorld(), CheatInstigator, Targets);
}
//--------------------------------------------------------------------------------------------------------------------------
ECogEngineCheat_ActiveState ACogEngineReplicator::IsCheatActiveOnTargets(const TArray<AActor*>& Targets, const FCogEngineCheat& Cheat)
ECogEngineCheat_ActiveState ACogEngineReplicator::IsCheatActiveOnTargets(const TArray<AActor*>& Targets, const FCogEngineCheat& Cheat) const
{
if (Cheat.Execution == nullptr)
{
return ECogEngineCheat_ActiveState::Inactive;
}
return Cheat.Execution->IsActiveOnTargets(Targets);
return Cheat.Execution->IsActiveOnTargets(GetWorld(), Targets);
}
@@ -43,18 +43,25 @@ void FCogEngineWindow_Cheats::Initialize()
{
if (InArgs.Num() > 0)
{
if (const FCogEngineCheat* cheat = FindCheatByName(InArgs[0], false))
{
const bool ApplyToEnemies = InArgs.Contains("-Enemies");
const bool ApplyToAllies = InArgs.Contains("-Allies");
const bool ApplyToControlled = InArgs.Contains("-Controlled");
RequestCheat(GetLocalPlayerPawn(), GetSelection(), *cheat, ApplyToEnemies, ApplyToAllies, ApplyToControlled);
}
else
const FCogEngineCheat* Cheat = FindCheatByName(InArgs[0], false);
if (Cheat == nullptr)
{
UE_LOG(LogCogImGui, Warning, TEXT("Cog.Cheat %s | Cheat not found"), *InArgs[0]);
return;
}
ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*InWorld);
if (Replicator == nullptr)
{
UE_LOG(LogCogImGui, Warning, TEXT("Cog.Cheat %s | Repliactor not found"), *InArgs[0]);
return;
}
const bool ApplyToEnemies = InArgs.Contains("-Enemies");
const bool ApplyToAllies = InArgs.Contains("-Allies");
const bool ApplyToControlled = InArgs.Contains("-Controlled");
RequestCheat(*Replicator, GetLocalPlayerPawn(), GetSelection(), *Cheat, ApplyToEnemies, ApplyToAllies, ApplyToControlled);
}
}));
@@ -64,12 +71,12 @@ void FCogEngineWindow_Cheats::Initialize()
for (const FCogEngineCheatCategory& CheatCategory : Asset->CheatCategories)
{
for (const FCogEngineCheat& Cheat : CheatCategory.PersistentEffects)
for (const FCogEngineCheat& Cheat : CheatCategory.PersistentCheats)
{
UpdateCheatColor(Cheat);
}
for (const FCogEngineCheat& Cheat : CheatCategory.InstantEffects)
for (const FCogEngineCheat& Cheat : CheatCategory.InstantCheats)
{
UpdateCheatColor(Cheat);
}
@@ -179,6 +186,12 @@ void FCogEngineWindow_Cheats::RenderContent()
return;
}
ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*GetWorld());
if (Replicator == nullptr)
{
ImGui::TextDisabled("No Replicator");
}
if (ImGui::BeginMenuBar())
{
if (ImGui::BeginMenu("Options"))
@@ -276,9 +289,9 @@ void FCogEngineWindow_Cheats::RenderContent()
}
int Index = 0;
for (const FCogEngineCheat& Cheat : CheatCategory.PersistentEffects)
for (const FCogEngineCheat& Cheat : CheatCategory.PersistentCheats)
{
AddCheat(Index, ControlledActor, SelectedActor, Cheat, true);
AddCheat(*Replicator, Index, ControlledActor, SelectedActor, Cheat, true);
Index++;
}
@@ -290,10 +303,10 @@ void FCogEngineWindow_Cheats::RenderContent()
//----------------------------------------------------------------------------
if (SelectedActor == ControlledActor)
{
for (const FCogEngineCheat& Cheat : CheatCategory.PersistentEffects)
for (const FCogEngineCheat& Cheat : CheatCategory.PersistentCheats)
{
TArray<AActor*> Targets = { SelectedActor };
if (ACogEngineReplicator::IsCheatActiveOnTargets(Targets, Cheat) == ECogEngineCheat_ActiveState::Active)
if (Replicator->IsCheatActiveOnTargets(Targets, Cheat) == ECogEngineCheat_ActiveState::Active)
{
Config->AppliedCheats.AddUnique(Cheat.Name);
}
@@ -307,9 +320,9 @@ void FCogEngineWindow_Cheats::RenderContent()
ImGui::TableNextColumn();
Index = 0;
for (const FCogEngineCheat& Cheat : CheatCategory.InstantEffects)
for (const FCogEngineCheat& Cheat : CheatCategory.InstantCheats)
{
AddCheat(Index, ControlledActor, SelectedActor, Cheat, false);
AddCheat(*Replicator, Index, ControlledActor, SelectedActor, Cheat, false);
Index++;
}
@@ -327,7 +340,7 @@ void FCogEngineWindow_Cheats::RenderContent()
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogEngineWindow_Cheats::AddCheat(const int32 Index, AActor* ControlledActor, AActor* SelectedActor, const FCogEngineCheat& Cheat, bool IsPersistent)
bool FCogEngineWindow_Cheats::AddCheat(ACogEngineReplicator& Replicator, const int32 Index, AActor* ControlledActor, AActor* SelectedActor, const FCogEngineCheat& Cheat, bool IsPersistent)
{
const auto CheatName = StringCast<ANSICHAR>(*Cheat.Name);
@@ -346,10 +359,10 @@ bool FCogEngineWindow_Cheats::AddCheat(const int32 Index, AActor* ControlledActo
if (IsPersistent)
{
TArray<AActor*> Targets = { SelectedActor };
bool isEnabled = ACogEngineReplicator::IsCheatActiveOnTargets(Targets, Cheat) == ECogEngineCheat_ActiveState::Active;
bool isEnabled = Replicator.IsCheatActiveOnTargets(Targets, Cheat) == ECogEngineCheat_ActiveState::Active;
if (ImGui::Checkbox(CheatName.Get(), &isEnabled))
{
RequestCheat(ControlledActor, SelectedActor, Cheat, IsShiftDown, IsAltDown, IsControlDown);
RequestCheat(Replicator, ControlledActor, SelectedActor, Cheat, IsShiftDown, IsAltDown, IsControlDown);
bIsPressed = true;
}
}
@@ -357,7 +370,7 @@ bool FCogEngineWindow_Cheats::AddCheat(const int32 Index, AActor* ControlledActo
{
if (ImGui::Button(CheatName.Get(), ImVec2(-1, 0)))
{
RequestCheat(ControlledActor, SelectedActor, Cheat, IsShiftDown, IsAltDown, IsControlDown);
RequestCheat(Replicator, ControlledActor, SelectedActor, Cheat, IsShiftDown, IsAltDown, IsControlDown);
bIsPressed = true;
}
}
@@ -365,10 +378,10 @@ bool FCogEngineWindow_Cheats::AddCheat(const int32 Index, AActor* ControlledActo
if (ImGui::IsItemHovered())
{
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::TextColored(ImVec4(1.0f, 1.0f, 1.0f, IsShiftDown || IsAltDown || IsControlDown ? 0.5f : 1.0f), "Selection");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, IsShiftDown ? 1.0f : 0.5f), "Enemies [SHIFT]");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, IsAltDown ? 1.0f : 0.5f), "Allies [ALT]");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, IsControlDown ? 1.0f : 0.5f), "Controlled [CTRL]");
ImGui::EndTooltip();
}
@@ -380,7 +393,7 @@ bool FCogEngineWindow_Cheats::AddCheat(const int32 Index, AActor* ControlledActo
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Cheats::RequestCheat(AActor* ControlledActor, AActor* SelectedActor, const FCogEngineCheat& Cheat, bool ApplyToEnemies, bool ApplyToAllies, bool ApplyToControlled)
void FCogEngineWindow_Cheats::RequestCheat(ACogEngineReplicator& Replicator, AActor* ControlledActor, AActor* SelectedActor, const FCogEngineCheat& Cheat, bool ApplyToEnemies, bool ApplyToAllies, bool ApplyToControlled)
{
TArray<AActor*> Actors;
@@ -416,14 +429,7 @@ void FCogEngineWindow_Cheats::RequestCheat(AActor* ControlledActor, AActor* Sele
Actors.Add(SelectedActor);
}
if (ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*GetWorld()))
{
Replicator->Server_ApplyCheat(ControlledActor, Actors, Cheat);
}
else
{
UE_LOG(LogCogImGui, Warning, TEXT("FCogAbilityWindow_Cheats::RequestCheat | Replicator not found"));
}
Replicator.Server_ApplyCheat(ControlledActor, Actors, Cheat);
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -431,7 +437,7 @@ const FCogEngineCheat* FCogEngineWindow_Cheats::FindCheatByName(const FString& C
{
for (const FCogEngineCheatCategory& CheatCategory : Asset->CheatCategories)
{
for (const FCogEngineCheat& Cheat : CheatCategory.PersistentEffects)
for (const FCogEngineCheat& Cheat : CheatCategory.PersistentCheats)
{
if (Cheat.Name == CheatName)
{
@@ -444,7 +450,7 @@ const FCogEngineCheat* FCogEngineWindow_Cheats::FindCheatByName(const FString& C
continue;
}
for (const FCogEngineCheat& Cheat : CheatCategory.InstantEffects)
for (const FCogEngineCheat& Cheat : CheatCategory.InstantCheats)
{
if (Cheat.Name == CheatName)
{
@@ -16,7 +16,7 @@ enum class ECogEngineCheat_ActiveState : uint8
};
//--------------------------------------------------------------------------------------------------------------------------
UCLASS(BlueprintType, Abstract, Const, DefaultToInstanced, EditInlineNew, CollapseCategories)
UCLASS(BlueprintType, Blueprintable, Abstract, Const, DefaultToInstanced, EditInlineNew, CollapseCategories, Meta = (ShowWorldContextPin))
class COGENGINE_API UCogEngineCheat_Execution
: public UObject
{
@@ -24,11 +24,11 @@ class COGENGINE_API UCogEngineCheat_Execution
public:
UFUNCTION(BlueprintNativeEvent)
void Execute(const AActor* Instigator, const TArray<AActor*>& Targets) const;
UFUNCTION(BlueprintNativeEvent, meta = (DevelopmentOnly, WorldContext = "WorldContextObject"))
void Execute(const UObject* WorldContextObject, const AActor* Instigator, const TArray<AActor*>& Targets) const;
UFUNCTION(BlueprintNativeEvent)
ECogEngineCheat_ActiveState IsActiveOnTargets(const TArray<AActor*>& Targets) const;
UFUNCTION(BlueprintNativeEvent, meta = (DevelopmentOnly, WorldContext = "WorldContextObject"))
ECogEngineCheat_ActiveState IsActiveOnTargets(const UObject* WorldContextObject, const TArray<AActor*>& Targets) const;
virtual bool GetColor(const FCogWindow& InCallingWindow, FLinearColor& OutColor) const;
};
@@ -61,10 +61,10 @@ struct COGENGINE_API FCogEngineCheatCategory
FString Name;
UPROPERTY(Category = "Cheats", EditAnywhere, meta = (TitleProperty = "Name"))
TArray<FCogEngineCheat> PersistentEffects;
TArray<FCogEngineCheat> PersistentCheats;
UPROPERTY(Category = "Cheats", EditAnywhere, meta = (TitleProperty = "Name"))
TArray<FCogEngineCheat> InstantEffects;
TArray<FCogEngineCheat> InstantCheats;
};
//--------------------------------------------------------------------------------------------------------------------------
@@ -54,7 +54,7 @@ public:
UFUNCTION(Reliable, Server)
void Server_ApplyCheat(const AActor* CheatInstigator, const TArray<AActor*>& TargetActors, const FCogEngineCheat& Cheat) const;
static ECogEngineCheat_ActiveState IsCheatActiveOnTargets(const TArray<AActor*>& Targets, const FCogEngineCheat& Cheat);
ECogEngineCheat_ActiveState IsCheatActiveOnTargets(const TArray<AActor*>& Targets, const FCogEngineCheat& Cheat) const;
protected:
@@ -5,6 +5,7 @@
#include "CogWindow.h"
#include "CogEngineWindow_Cheats.generated.h"
class ACogEngineReplicator;
class AActor;
class UCogEngineConfig_Cheats;
class UCogEngineDataAsset;
@@ -29,9 +30,9 @@ protected:
virtual void TryReapplyCheats();
virtual bool AddCheat(const int32 Index, AActor* ControlledActor, AActor* TargetActor, const FCogEngineCheat& CheatEffect, bool IsPersistent);
virtual bool AddCheat(ACogEngineReplicator& Replicator, const int32 Index, AActor* ControlledActor, AActor* TargetActor, const FCogEngineCheat& CheatEffect, bool IsPersistent);
virtual void RequestCheat(AActor* ControlledActor, AActor* SelectedActor, const FCogEngineCheat& Cheat, bool ApplyToEnemies, bool ApplyToAllies, bool ApplyToControlled);
virtual void RequestCheat(ACogEngineReplicator& Replicator, AActor* ControlledActor, AActor* SelectedActor, const FCogEngineCheat& Cheat, bool ApplyToEnemies, bool ApplyToAllies, bool ApplyToControlled);
virtual const FCogEngineCheat* FindCheatByName(const FString& CheatName, const bool OnlyPersistentCheats);
@@ -0,0 +1,115 @@
#include "CogAbilityCheat_Execution_ActivateAbility.h"
#include "CogAbilityDataAsset.h"
#include "AbilitySystemComponent.h"
#include "AbilitySystemGlobals.h"
#include "CogAbilityConfig_Alignment.h"
#include "CogCommon.h"
#include "CogImguiHelper.h"
#include "CogWindow.h"
//--------------------------------------------------------------------------------------------------------------------------
void UCogAbilityCheat_Execution_ActivateAbility::Execute_Implementation(const UObject* WorldContextObject, const AActor* Instigator, const TArray<AActor*>& Targets) const
{
if (Ability == nullptr)
{ return; }
for (AActor* Target : Targets)
{
UAbilitySystemComponent* AbilitySystem = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(Target, true);
if (AbilitySystem == nullptr)
{
COG_LOG_FUNC(LogCogImGui, ELogVerbosity::Warning, TEXT("Target:%s | Invalid Target AbilitySystem"), *GetNameSafe(Target));
continue;
}
FGameplayAbilitySpecHandle Handle;
const FGameplayAbilitySpec* Spec = AbilitySystem->FindAbilitySpecFromClass(Ability);
if (Spec != nullptr)
{
if (Spec->IsActive())
{
AbilitySystem->CancelAbilityHandle(Spec->Handle);
if (RemoveAbilityOnEnd)
{
AbilitySystem->ClearAbility(Handle);
}
return;
}
Handle = Spec->Handle;
}
else
{
Handle = AbilitySystem->GiveAbility(FGameplayAbilitySpec(Ability, 1, INDEX_NONE, Target));
Spec = AbilitySystem->FindAbilitySpecFromHandle(Handle, EConsiderPending::All);
}
AbilitySystem->TryActivateAbility(Handle);
if (Spec->IsActive() == false)
{
if (RemoveAbilityOnEnd)
{
AbilitySystem->ClearAbility(Handle);
}
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
ECogEngineCheat_ActiveState UCogAbilityCheat_Execution_ActivateAbility::IsActiveOnTargets_Implementation(const UObject* WorldContextObject, const TArray<AActor*>& Targets) const
{
if (Ability == nullptr)
{
return ECogEngineCheat_ActiveState::Inactive;
}
int32 NumActiveAbilities = 0;
for (const AActor* Target : Targets)
{
const UAbilitySystemComponent* AbilitySystem = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(Target, true);
if (AbilitySystem == nullptr)
{ continue; }
const FGameplayAbilitySpec* Spec = AbilitySystem->FindAbilitySpecFromClass(Ability);
if (Spec == nullptr)
{ continue; }
if (Spec->IsActive())
{
NumActiveAbilities++;
}
}
if (NumActiveAbilities == 0)
{
return ECogEngineCheat_ActiveState::Inactive;
}
if (NumActiveAbilities == Targets.Num())
{
return ECogEngineCheat_ActiveState::Active;
}
return ECogEngineCheat_ActiveState::Partial;
}
//--------------------------------------------------------------------------------------------------------------------------
bool UCogAbilityCheat_Execution_ActivateAbility::GetColor(const FCogWindow& InCallingWindow, FLinearColor& OutColor) const
{
if (Ability == nullptr)
{ return false; }
const UGameplayAbility* GameplayAbility = Ability->GetDefaultObject<UGameplayAbility>();
if (GameplayAbility == nullptr)
{ return false; }
const UCogAbilityConfig_Alignment* Config = InCallingWindow.GetConfig<UCogAbilityConfig_Alignment>();
const UCogAbilityDataAsset* Asset = InCallingWindow.GetAsset<UCogAbilityDataAsset>();
OutColor = Config->GetAbilityColor(Asset, *GameplayAbility);
return true;
}
@@ -9,7 +9,7 @@
#include "CogWindow.h"
//--------------------------------------------------------------------------------------------------------------------------
void UCogAbilityCheat_Execution_ApplyEffect::Execute_Implementation(const AActor* Instigator, const TArray<AActor*>& Targets) const
void UCogAbilityCheat_Execution_ApplyEffect::Execute_Implementation(const UObject* WorldContextObject, const AActor* Instigator, const TArray<AActor*>& Targets) const
{
UAbilitySystemComponent* DefaultInstigatorAbilitySystem = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(Instigator, true);
@@ -56,7 +56,7 @@ void UCogAbilityCheat_Execution_ApplyEffect::Execute_Implementation(const AActor
}
//--------------------------------------------------------------------------------------------------------------------------
ECogEngineCheat_ActiveState UCogAbilityCheat_Execution_ApplyEffect::IsActiveOnTargets_Implementation(const TArray<AActor*>& Targets) const
ECogEngineCheat_ActiveState UCogAbilityCheat_Execution_ApplyEffect::IsActiveOnTargets_Implementation(const UObject* WorldContextObject, const TArray<AActor*>& Targets) const
{
if (Effect == nullptr)
{
@@ -23,25 +23,34 @@ FVector4f UCogAbilityConfig_Alignment::GetAttributeColor(const UAbilitySystemCom
return NeutralColor;
}
//--------------------------------------------------------------------------------------------------------------------------
FVector4f UCogAbilityConfig_Alignment::GetAbilityColor(const UCogAbilityDataAsset* Asset, const UGameplayAbility& Ability) const
{
if (Asset == nullptr)
{ return NeutralColor; }
const FGameplayTagContainer& Tags = Ability.GetAssetTags();
if (Tags.HasTag(Asset->NegativeAbilityTag))
{ return NegativeColor; }
if (Tags.HasTag(Asset->PositiveAbilityTag))
{ return PositiveColor; }
return NeutralColor;
}
//--------------------------------------------------------------------------------------------------------------------------
FVector4f UCogAbilityConfig_Alignment::GetEffectColor(const UCogAbilityDataAsset* Asset, const UGameplayEffect& Effect) const
{
if (Asset == nullptr)
{
return NeutralColor;
}
{ return NeutralColor; }
const FGameplayTagContainer& Tags = Effect.GetAssetTags();
if (Tags.HasTag(Asset->NegativeEffectTag))
{
return NegativeColor;
}
{ return NegativeColor; }
if (Tags.HasTag(Asset->PositiveEffectTag))
{
return PositiveColor;
}
{ return PositiveColor; }
return NeutralColor;
}
@@ -1,114 +1,11 @@
#include "CogAbilityWindow_Cheats.h"
#include "CogAbilityConfig_Alignment.h"
#include "CogAbilityDataAsset.h"
#include "CogAbilityReplicator.h"
#include "CogCommonAllegianceActorInterface.h"
#include "CogImguiHelper.h"
#include "CogWindowConsoleCommandManager.h"
#include "CogWindowWidgets.h"
#include "EngineUtils.h"
#include "GameFramework/Character.h"
#include "imgui.h"
#include "imgui_internal.h"
//--------------------------------------------------------------------------------------------------------------------------
void FCogAbilityWindow_Cheats::Initialize()
{
Super::Initialize();
bHasMenu = true;
Asset = GetAsset<UCogAbilityDataAsset>();
Config = GetConfig<UCogAbilityConfig_Cheats>();
AlignmentConfig = GetConfig<UCogAbilityConfig_Alignment>();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogAbilityWindow_Cheats::RenderHelp()
{
ImGui::Text(
"This window can be used to apply cheats to the selected actor (by default). "
"The cheats can be configured in the '%s' data asset. "
"When clicking a cheat button, press:\n"
" [CTRL] to apply the cheat to controlled actor\n"
" [ALT] to apply the cheat to the allies of the selected actor\n"
" [SHIFT] to apply the cheat to the enemies of the selected actor\n"
, TCHAR_TO_ANSI(*GetNameSafe(Asset.Get()))
);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogAbilityWindow_Cheats::GameTick(float DeltaTime)
{
Super::GameTick(DeltaTime);
TryReapplyCheats();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogAbilityWindow_Cheats::TryReapplyCheats()
{
if (Config == nullptr)
{
return;
}
if (bHasReappliedCheats)
{
return;
}
if (Config->bReapplyCheatsBetweenPlays == false)
{
return;
}
static int32 IsFirstLaunch = true;
if (IsFirstLaunch && Config->bReapplyCheatsBetweenLaunches == false)
{
return;
}
IsFirstLaunch = false;
if (Asset == nullptr)
{
return;
}
APawn* ControlledActor = GetLocalPlayerPawn();
if (ControlledActor == nullptr)
{
return;
}
ACogAbilityReplicator* Replicator = ACogAbilityReplicator::GetFirstReplicator(*GetWorld());
if (Replicator == nullptr)
{
return;
}
TArray<AActor*> Targets { ControlledActor };
for (int32 i = Config->AppliedCheats.Num() - 1; i >= 0; i--)
{
const FString& AppliedCheatName = Config->AppliedCheats[i];
if (const FCogAbilityCheat* Cheat = Asset->PersistentEffects.FindByPredicate(
[AppliedCheatName](const FCogAbilityCheat& Cheat) { return Cheat.Name == AppliedCheatName; }))
{
Replicator->Server_ApplyCheat(ControlledActor, Targets, *Cheat);
}
else
{
//-----------------------------------------------------
// This cheat doesn't exist anymore. We can remove it.
//-----------------------------------------------------
Config->AppliedCheats.RemoveAt(i);
}
}
bHasReappliedCheats = true;
ImGui::TextDisabled("This window is deprecated. Please use the CogEngineWindow_Cheat instead as it provide more functionnalities.");
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -116,235 +13,5 @@ void FCogAbilityWindow_Cheats::RenderContent()
{
Super::RenderContent();
if (Config == nullptr)
{
ImGui::TextDisabled("Invalid Config");
return;
}
AActor* SelectedActor = GetSelection();
if (SelectedActor == nullptr)
{
ImGui::TextDisabled("Invalid Selection");
return;
}
if (Asset == nullptr)
{
ImGui::TextDisabled("Invalid Asset");
return;
}
if (ImGui::BeginMenuBar())
{
if (ImGui::BeginMenu("Options"))
{
ImGui::Checkbox("Reapply Cheats Between Plays", &Config->bReapplyCheatsBetweenPlays);
if (Config->bReapplyCheatsBetweenPlays == false)
{
ImGui::BeginDisabled();
}
ImGui::Checkbox("Reapply Cheats Between Launches", &Config->bReapplyCheatsBetweenLaunches);
if (Config->bReapplyCheatsBetweenPlays == false)
{
ImGui::EndDisabled();
}
ImGui::Separator();
ImGui::ColorEdit4("Positive Color", (float*)&AlignmentConfig->PositiveColor, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaPreviewHalf);
ImGui::ColorEdit4("Negative Color", (float*)&AlignmentConfig->NegativeColor, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaPreviewHalf);
ImGui::ColorEdit4("Neutral Color", (float*)&AlignmentConfig->NeutralColor, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaPreviewHalf);
ImGui::Separator();
if (ImGui::MenuItem("Reset"))
{
ResetConfig();
}
ImGui::EndMenu();
}
ImGui::EndMenuBar();
}
APawn* ControlledActor = 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 : Asset->PersistentEffects)
{
ImGui::PushID(Index);
AddCheat(ControlledActor, SelectedActor, CheatEffect, true);
ImGui::PopID();
Index++;
}
//----------------------------------------------------------------------------
// Update the config of applied cheat to reapply them on the next launch.
// We do not updated them only when the the user input is pressed because
// the state of the cheat is lagging when connected to a server.
// So we check if the array should be updated all the time.
//----------------------------------------------------------------------------
if (SelectedActor == ControlledActor)
{
for (const FCogAbilityCheat& CheatEffect : Asset->PersistentEffects)
{
if (ACogAbilityReplicator::IsCheatActive(SelectedActor, CheatEffect))
{
Config->AppliedCheats.AddUnique(CheatEffect.Name);
}
else
{
Config->AppliedCheats.Remove(CheatEffect.Name);
}
}
}
ImGui::TableNextColumn();
for (const FCogAbilityCheat& CheatEffect : Asset->InstantEffects)
{
ImGui::PushID(Index);
AddCheat(ControlledActor, SelectedActor, CheatEffect, false);
ImGui::PopID();
Index++;
}
ImGui::EndTable();
}
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogAbilityWindow_Cheats::AddCheat(AActor* ControlledActor, AActor* SelectedActor, const FCogAbilityCheat& Cheat, bool IsPersistent)
{
if (Cheat.Effect == nullptr)
{
return false;
}
const UGameplayEffect* EffectCDO = Cheat.Effect->GetDefaultObject<UGameplayEffect>();
if (EffectCDO != nullptr)
{
FCogWindowWidgets::PushBackColor(FCogImguiHelper::ToImVec4(AlignmentConfig->GetEffectColor(Asset, *EffectCDO)));
}
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;
bool bIsPressed = false;
if (IsPersistent)
{
bool isEnabled = ACogAbilityReplicator::IsCheatActive(SelectedActor, Cheat);
if (ImGui::Checkbox(TCHAR_TO_ANSI(*Cheat.Name), &isEnabled))
{
RequestCheat(ControlledActor, SelectedActor, Cheat, IsShiftDown, IsAltDown, IsControlDown);
bIsPressed = true;
}
}
else
{
if (ImGui::Button(TCHAR_TO_ANSI(*Cheat.Name), ImVec2(-1, 0)))
{
RequestCheat(ControlledActor, SelectedActor, Cheat, IsShiftDown, IsAltDown, IsControlDown);
bIsPressed = true;
}
}
if (ImGui::IsItemHovered())
{
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();
}
if (EffectCDO != nullptr)
{
FCogWindowWidgets::PopBackColor();
}
return bIsPressed;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogAbilityWindow_Cheats::RequestCheat(AActor* ControlledActor, AActor* SelectedActor, const FCogAbilityCheat& Cheat, bool ApplyToEnemies, bool ApplyToAllies, bool ApplyToControlled)
{
TArray<AActor*> Actors;
if (ApplyToControlled)
{
Actors.Add(ControlledActor);
}
if (ApplyToEnemies || ApplyToAllies)
{
for (TActorIterator<ACharacter> It(GetWorld(), ACharacter::StaticClass()); It; ++It)
{
if (AActor* OtherActor = *It)
{
ECogCommonAllegiance Allegiance = ECogCommonAllegiance::Enemy;
if (ICogCommonAllegianceActorInterface* AllegianceInterface = Cast<ICogCommonAllegianceActorInterface>(OtherActor))
{
Allegiance = AllegianceInterface->GetAllegianceWithOtherActor(ControlledActor);
}
if ((ApplyToEnemies && (Allegiance == ECogCommonAllegiance::Enemy))
|| (ApplyToAllies && (Allegiance == ECogCommonAllegiance::Friendly)))
{
Actors.Add(OtherActor);
}
}
}
}
if ((ApplyToControlled || ApplyToEnemies || ApplyToAllies) == false)
{
Actors.Add(SelectedActor);
}
if (ACogAbilityReplicator* Replicator = ACogAbilityReplicator::GetFirstReplicator(*GetWorld()))
{
Replicator->Server_ApplyCheat(ControlledActor, Actors, Cheat);
}
else
{
UE_LOG(LogCogImGui, Warning, TEXT("FCogAbilityWindow_Cheats::RequestCheat | Replicator not found"));
}
}
//--------------------------------------------------------------------------------------------------------------------------
const FCogAbilityCheat* FCogAbilityWindow_Cheats::FindCheatByName(const FString& CheatName)
{
for (const FCogAbilityCheat& cheat : Asset->PersistentEffects)
{
if (cheat.Name == CheatName)
{
return &cheat;
}
}
for (const FCogAbilityCheat& cheat : Asset->InstantEffects)
{
if (cheat.Name == CheatName)
{
return &cheat;
}
}
return nullptr;
}
RenderHelp();
}
@@ -0,0 +1,27 @@
#pragma once
#include "CoreMinimal.h"
#include "CogEngineDataAsset.h"
#include "GameplayEffect.h"
#include "CogAbilityCheat_Execution_ActivateAbility.generated.h"
//--------------------------------------------------------------------------------------------------------------------------
UCLASS(DisplayName = "Activate Ability")
class COGABILITY_API UCogAbilityCheat_Execution_ActivateAbility
: public UCogEngineCheat_Execution
{
GENERATED_BODY()
public:
virtual void Execute_Implementation(const UObject* WorldContextObject, const AActor* Instigator, const TArray<AActor*>& Targets) const override;
virtual ECogEngineCheat_ActiveState IsActiveOnTargets_Implementation(const UObject* WorldContextObject, const TArray<AActor*>& Targets) const override;
virtual bool GetColor(const FCogWindow& InCallingWindow, FLinearColor& OutColor) const override;
UPROPERTY(EditAnywhere)
TSubclassOf<UGameplayAbility> Ability;
UPROPERTY(EditAnywhere)
bool RemoveAbilityOnEnd = true;
};
@@ -13,9 +13,9 @@ class COGABILITY_API UCogAbilityCheat_Execution_ApplyEffect
GENERATED_BODY()
public:
void Execute_Implementation(const AActor* Instigator, const TArray<AActor*>& Targets) const override;
virtual void Execute_Implementation(const UObject* WorldContextObject, const AActor* Instigator, const TArray<AActor*>& Targets) const override;
ECogEngineCheat_ActiveState IsActiveOnTargets_Implementation(const TArray<AActor*>& Targets) const override;
virtual ECogEngineCheat_ActiveState IsActiveOnTargets_Implementation(const UObject* WorldContextObject, const TArray<AActor*>& Targets) const override;
virtual bool GetColor(const FCogWindow& InCallingWindow, FLinearColor& OutColor) const override;
@@ -2,6 +2,7 @@
#include "CoreMinimal.h"
#include "CogCommonConfig.h"
#include "Abilities/GameplayAbility.h"
#include "CogAbilityConfig_Alignment.generated.h"
class UAbilitySystemComponent;
@@ -22,13 +23,14 @@ public:
FVector4f GetAttributeColor(const UAbilitySystemComponent& AbilitySystemComponent, const FGameplayAttribute& Attribute) const;
FVector4f GetAbilityColor(const UCogAbilityDataAsset* Asset, const UGameplayAbility& Ability) const;
FVector4f GetEffectModifierColor(const FModifierSpec& ModSpec, const FGameplayModifierInfo& ModInfo, float BaseValue) const;
FVector4f GetEffectModifierColor(float ModifierValue, EGameplayModOp::Type ModifierOp, float BaseValue) const;
FVector4f GetEffectColor(const UCogAbilityDataAsset* Asset, const UGameplayEffect& Effect) const;
UPROPERTY(Config)
FVector4f PositiveColor = FVector4f(0.0f, 1.0f, 0.5f, 1.0f);
@@ -151,6 +151,12 @@ public:
UPROPERTY(Category = "Cheats", EditAnywhere)
FGameplayTag PositiveEffectTag;
UPROPERTY(Category="Cheats", EditAnywhere)
FGameplayTag NegativeAbilityTag;
UPROPERTY(Category = "Cheats", EditAnywhere)
FGameplayTag PositiveAbilityTag;
UPROPERTY(Category = "Cheats", EditAnywhere, meta = (TitleProperty = "Name"))
TArray<FCogAbilityCheat> PersistentEffects;
@@ -16,35 +16,11 @@ class COGABILITY_API FCogAbilityWindow_Cheats : public FCogWindow
{
typedef FCogWindow Super;
public:
virtual void Initialize() override;
protected:
virtual void GameTick(float DeltaTime) override;
virtual void RenderHelp() override;
virtual void RenderContent() override;
virtual void TryReapplyCheats();
APawn* GetCheatInstigator();
virtual bool AddCheat(AActor* ControlledActor, AActor* TargetActor, const FCogAbilityCheat& CheatEffect, bool IsPersistent);
virtual void RequestCheat(AActor* ControlledActor, AActor* SelectedActor, const FCogAbilityCheat& Cheat, bool ApplyToEnemies, bool ApplyToAllies, bool ApplyToControlled);
virtual const FCogAbilityCheat* FindCheatByName(const FString& CheatName);
TObjectPtr<const UCogAbilityDataAsset> Asset = nullptr;
TObjectPtr<UCogAbilityConfig_Cheats> Config = nullptr;
TObjectPtr<UCogAbilityConfig_Alignment> AlignmentConfig = nullptr;
bool bHasReappliedCheats = false;
};
//--------------------------------------------------------------------------------------------------------------------------