From af565bf70dd132c524fa6fa09a47b36ac184b64c Mon Sep 17 00:00:00 2001 From: Arnaud Jamin Date: Tue, 7 Jan 2025 00:38:44 -0500 Subject: [PATCH] Fix cheat window not working on dedicated game server (when using netimgui) Also add cheat commands: Cog.Cheat -Allies -Enemies -Controlled --- .../Source/CogWindow/Private/CogWindow.cpp | 1 + .../CogWindow/Private/CogWindowManager.cpp | 1 - .../Private/CogAbilityReplicator.cpp | 20 ++-- .../Private/CogAbilityWindow_Cheats.cpp | 94 ++++++++++++++----- .../Public/CogAbilityWindow_Cheats.h | 5 +- 5 files changed, 88 insertions(+), 33 deletions(-) diff --git a/Plugins/Cog/Source/CogWindow/Private/CogWindow.cpp b/Plugins/Cog/Source/CogWindow/Private/CogWindow.cpp index 7c79cfd..76bb9ab 100644 --- a/Plugins/Cog/Source/CogWindow/Private/CogWindow.cpp +++ b/Plugins/Cog/Source/CogWindow/Private/CogWindow.cpp @@ -149,6 +149,7 @@ void FCogWindow::SetIsVisible(const bool Value) OnWindowVisibilityChanged(Value); } +//-------------------------------------------------------------------------------------------------------------------------- APawn* FCogWindow::GetLocalPlayerPawn() const { const APlayerController* LocalPlayerController = GetLocalPlayerController(); diff --git a/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp b/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp index c27d390..708c02e 100644 --- a/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp +++ b/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp @@ -14,7 +14,6 @@ #include "HAL/IConsoleManager.h" #include "imgui_internal.h" #include "Misc/CoreMisc.h" -#include "Misc/EngineVersionComparison.h" #include "NetImgui_Api.h" FString UCogWindowManager::ToggleInputCommand = TEXT("Cog.ToggleInput"); diff --git a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityReplicator.cpp b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityReplicator.cpp index a84d8f7..213f803 100644 --- a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityReplicator.cpp +++ b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityReplicator.cpp @@ -3,6 +3,7 @@ #include "AbilitySystemComponent.h" #include "AbilitySystemGlobals.h" #include "CogAbilityDataAsset.h" +#include "CogImguiHelper.h" #include "CogWindowHelper.h" #include "Components/SceneComponent.h" #include "Engine/World.h" @@ -30,8 +31,10 @@ ACogAbilityReplicator* ACogAbilityReplicator::GetFirstReplicator(const UWorld& W { for (TActorIterator It(&World, StaticClass()); It; ++It) { - ACogAbilityReplicator* Replicator = *It; - return Replicator; + if (ACogAbilityReplicator* Replicator = *It) + { + return Replicator; + } } return nullptr; @@ -95,17 +98,14 @@ void ACogAbilityReplicator::EndPlay(const EEndPlayReason::Type EndPlayReason) //-------------------------------------------------------------------------------------------------------------------------- void ACogAbilityReplicator::Server_ApplyCheat_Implementation(const AActor* CheatInstigator, const TArray& Targets, const FCogAbilityCheat& Cheat) const { - UAbilitySystemComponent* InstigatorAbilitySystem = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(CheatInstigator, true); - if (InstigatorAbilitySystem == nullptr) - { - return; - } + UAbilitySystemComponent* DefaultInstigatorAbilitySystem = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(CheatInstigator, true); for (AActor* Target : Targets) { UAbilitySystemComponent* TargetAbilitySystem = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(Target, true); if (TargetAbilitySystem == nullptr) { + UE_LOG(LogCogImGui, Warning, TEXT("ACogAbilityReplicator::Server_ApplyCheat_Implementation | Target:%s | Invalid Target AbilitySystem"), *GetNameSafe(Target)); continue; } @@ -115,6 +115,12 @@ void ACogAbilityReplicator::Server_ApplyCheat_Implementation(const AActor* Cheat } else { + //----------------------------------------------------------------------------------- + // When executing a cheat directly on the game server, there is not an obvious + // local player to use as the instigator. Instead, we use the target ability system. + //----------------------------------------------------------------------------------- + UAbilitySystemComponent* InstigatorAbilitySystem = (DefaultInstigatorAbilitySystem != nullptr) ? DefaultInstigatorAbilitySystem : TargetAbilitySystem; + FGameplayEffectContextHandle ContextHandle = InstigatorAbilitySystem->MakeEffectContext(); ContextHandle.AddSourceObject(InstigatorAbilitySystem); FGameplayEffectSpecHandle SpecHandle = InstigatorAbilitySystem->MakeOutgoingSpec(Cheat.Effect, 1, ContextHandle); diff --git a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Cheats.cpp b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Cheats.cpp index 644f0af..fed189a 100644 --- a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Cheats.cpp +++ b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Cheats.cpp @@ -5,6 +5,7 @@ #include "CogAbilityReplicator.h" #include "CogCommonAllegianceActorInterface.h" #include "CogImguiHelper.h" +#include "CogWindowConsoleCommandManager.h" #include "CogWindowWidgets.h" #include "EngineUtils.h" #include "GameFramework/Character.h" @@ -21,6 +22,29 @@ void FCogAbilityWindow_Cheats::Initialize() Asset = GetAsset(); Config = GetConfig(); AlignmentConfig = GetConfig(); + + FCogWindowConsoleCommandManager::RegisterWorldConsoleCommand( + TEXT("Cog.Cheat"), + TEXT("Apply a cheat to the selection. Cog.Cheat -Allies -Enemies -Controlled"), + GetWorld(), + FCogWindowConsoleCommandDelegate::CreateLambda([this](const TArray& InArgs, UWorld* InWorld) + { + if (InArgs.Num() > 0) + { + if (const FCogAbilityCheat* cheat = FindCheatByName(InArgs[0])) + { + 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 + { + UE_LOG(LogCogImGui, Warning, TEXT("Cog.Cheat %s | Cheat not found"), *InArgs[0]); + } + } + })); } //-------------------------------------------------------------------------------------------------------------------------- @@ -84,8 +108,8 @@ void FCogAbilityWindow_Cheats::TryReapplyCheats() return; } - APawn* LocalPawn = GetLocalPlayerPawn(); - if (LocalPawn == nullptr) + APawn* ControlledActor = GetLocalPlayerPawn(); + if (ControlledActor == nullptr) { return; } @@ -96,7 +120,7 @@ void FCogAbilityWindow_Cheats::TryReapplyCheats() return; } - TArray Targets { LocalPawn }; + TArray Targets { ControlledActor }; for (int32 i = Config->AppliedCheats.Num() - 1; i >= 0; i--) { @@ -105,7 +129,7 @@ void FCogAbilityWindow_Cheats::TryReapplyCheats() if (const FCogAbilityCheat* Cheat = Asset->PersistentEffects.FindByPredicate( [AppliedCheatName](const FCogAbilityCheat& Cheat) { return Cheat.Name == AppliedCheatName; })) { - Replicator->Server_ApplyCheat(LocalPawn, Targets, *Cheat); + Replicator->Server_ApplyCheat(ControlledActor, Targets, *Cheat); } else { @@ -247,13 +271,17 @@ bool FCogAbilityWindow_Cheats::AddCheat(AActor* ControlledActor, AActor* Selecte 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); + RequestCheat(ControlledActor, SelectedActor, Cheat, IsShiftDown, IsAltDown, IsControlDown); bIsPressed = true; } } @@ -261,22 +289,18 @@ bool FCogAbilityWindow_Cheats::AddCheat(AActor* ControlledActor, AActor* Selecte { if (ImGui::Button(TCHAR_TO_ANSI(*Cheat.Name), ImVec2(-1, 0))) { - RequestCheat(ControlledActor, SelectedActor, Cheat); + RequestCheat(ControlledActor, SelectedActor, Cheat, IsShiftDown, IsAltDown, IsControlDown); bIsPressed = true; } } 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::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(); } @@ -289,20 +313,16 @@ bool FCogAbilityWindow_Cheats::AddCheat(AActor* ControlledActor, AActor* Selecte } //-------------------------------------------------------------------------------------------------------------------------- -void FCogAbilityWindow_Cheats::RequestCheat(AActor* ControlledActor, AActor* SelectedActor, const FCogAbilityCheat& Cheat) +void FCogAbilityWindow_Cheats::RequestCheat(AActor* ControlledActor, AActor* SelectedActor, const FCogAbilityCheat& Cheat, bool ApplyToEnemies, bool ApplyToAllies, bool ApplyToControlled) { - 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 Actors; - if (IsControlDown) + if (ApplyToControlled) { Actors.Add(ControlledActor); } - if (IsShiftDown || IsAltDown) + if (ApplyToEnemies || ApplyToAllies) { for (TActorIterator It(GetWorld(), ACharacter::StaticClass()); It; ++It) { @@ -315,8 +335,8 @@ void FCogAbilityWindow_Cheats::RequestCheat(AActor* ControlledActor, AActor* Sel Allegiance = AllegianceInterface->GetAllegianceWithOtherActor(ControlledActor); } - if ((IsShiftDown && (Allegiance == ECogCommonAllegiance::Enemy)) - || (IsAltDown && (Allegiance == ECogCommonAllegiance::Friendly))) + if ((ApplyToEnemies && (Allegiance == ECogCommonAllegiance::Enemy)) + || (ApplyToAllies && (Allegiance == ECogCommonAllegiance::Friendly))) { Actors.Add(OtherActor); } @@ -324,7 +344,7 @@ void FCogAbilityWindow_Cheats::RequestCheat(AActor* ControlledActor, AActor* Sel } } - if ((IsControlDown || IsShiftDown || IsAltDown) == false) + if ((ApplyToControlled || ApplyToEnemies || ApplyToAllies) == false) { Actors.Add(SelectedActor); } @@ -333,4 +353,30 @@ void FCogAbilityWindow_Cheats::RequestCheat(AActor* ControlledActor, AActor* Sel { 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; } diff --git a/Plugins/CogAbility/Source/CogAbility/Public/CogAbilityWindow_Cheats.h b/Plugins/CogAbility/Source/CogAbility/Public/CogAbilityWindow_Cheats.h index 478ea92..dafa15b 100644 --- a/Plugins/CogAbility/Source/CogAbility/Public/CogAbilityWindow_Cheats.h +++ b/Plugins/CogAbility/Source/CogAbility/Public/CogAbilityWindow_Cheats.h @@ -31,10 +31,13 @@ protected: 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* TargetActor, const FCogAbilityCheat& CheatEffect); + virtual void RequestCheat(AActor* ControlledActor, AActor* SelectedActor, const FCogAbilityCheat& Cheat, bool ApplyToEnemies, bool ApplyToAllies, bool ApplyToControlled); + + virtual const FCogAbilityCheat* FindCheatByName(const FString& CheatName); TObjectPtr Asset = nullptr;