Files
Cog/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Cheats.cpp
T
Arnaud Jamin e72504b47a CogWindow: CogWindows are not UObject anymore
CogWindows are now normal object because we want to be able to Ifdef them, and UObject cannot be ifdef. CogWindows were UObject mainly for saving their config. The configs have been moved in separated class, which are UObject.
2023-10-27 02:39:33 -04:00

322 lines
10 KiB
C++

#include "CogAbilityWindow_Cheats.h"
#include "AbilitySystemGlobals.h"
#include "CogAbilityDataAsset.h"
#include "CogAbilityReplicator.h"
#include "CogCommonAllegianceActorInterface.h"
#include "CogDebugDraw.h"
#include "CogImguiHelper.h"
#include "CogWindowHelper.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>();
}
//--------------------------------------------------------------------------------------------------------------------------
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::ResetConfig()
{
Super::ResetConfig();
Config->Reset();
}
//--------------------------------------------------------------------------------------------------------------------------
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* LocalPawn = GetLocalPlayerPawn();
if (LocalPawn == nullptr)
{
return;
}
ACogAbilityReplicator* Replicator = ACogAbilityReplicator::GetLocalReplicator(*GetWorld());
if (Replicator == nullptr)
{
return;
}
TArray<AActor*> Targets { LocalPawn };
for (const FString& AppliedCheatName : Config->AppliedCheats)
{
if (const FCogAbilityCheat* Cheat = Asset->PersistentEffects.FindByPredicate(
[AppliedCheatName](const FCogAbilityCheat& Cheat) { return Cheat.Name == AppliedCheatName; }))
{
Replicator->ApplyCheat(LocalPawn, Targets, *Cheat);
}
}
bHasReappliedCheats = true;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogAbilityWindow_Cheats::RenderContent()
{
Super::RenderContent();
if (Config == nullptr)
{
ImGui::Text("Invalid Config");
return;
}
AActor* SelectedActor = GetSelection();
if (SelectedActor == nullptr)
{
ImGui::Text("Invalid Selection");
return;
}
if (Asset == nullptr)
{
ImGui::Text("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::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();
bool bHasChanged = false;
int Index = 0;
for (const FCogAbilityCheat& CheatEffect : Asset->PersistentEffects)
{
ImGui::PushID(Index);
bHasChanged |= AddCheat(ControlledActor, SelectedActor, CheatEffect, true);
ImGui::PopID();
Index++;
}
//----------------------------------------------------------------
// When a persistent cheat has been changed, update the applied
// cheats string array to be saved in the config later
//----------------------------------------------------------------
if (bHasChanged && SelectedActor == ControlledActor)
{
Config->AppliedCheats.Empty();
for (const FCogAbilityCheat& CheatEffect : Asset->PersistentEffects)
{
if (ACogAbilityReplicator::IsCheatActive(SelectedActor, CheatEffect))
{
Config->AppliedCheats.Add(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;
}
bool bIsPressed = false;
const FGameplayTagContainer& Tags = Cheat.Effect->GetDefaultObject<UGameplayEffect>()->InheritableGameplayEffectTags.CombinedTags;
FLinearColor Color;
if (Tags.HasTag(Asset->NegativeEffectTag))
{
Color = Asset->NegativeEffectColor;
}
else if (Tags.HasTag(Asset->PositiveEffectTag))
{
Color = Asset->PositiveEffectColor;
}
else
{
Color = Asset->NeutralEffectColor;
}
FCogWindowWidgets::PushBackColor(FCogImguiHelper::ToImVec4(Color));
if (IsPersistent)
{
bool isEnabled = ACogAbilityReplicator::IsCheatActive(SelectedActor, Cheat);
if (ImGui::Checkbox(TCHAR_TO_ANSI(*Cheat.Name), &isEnabled))
{
RequestCheat(ControlledActor, SelectedActor, Cheat);
bIsPressed = true;
}
}
else
{
if (ImGui::Button(TCHAR_TO_ANSI(*Cheat.Name), ImVec2(-1, 0)))
{
RequestCheat(ControlledActor, SelectedActor, Cheat);
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::EndTooltip();
}
FCogWindowWidgets::PopBackColor();
return bIsPressed;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogAbilityWindow_Cheats::RequestCheat(AActor* ControlledActor, 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(ControlledActor);
}
if (IsShiftDown || IsAltDown)
{
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 ((IsShiftDown && (Allegiance == ECogCommonAllegiance::Enemy))
|| (IsAltDown && (Allegiance == ECogCommonAllegiance::Friendly)))
{
Actors.Add(OtherActor);
}
}
}
}
if ((IsControlDown || IsShiftDown || IsAltDown) == false)
{
Actors.Add(SelectedActor);
}
if (ACogAbilityReplicator* Replicator = ACogAbilityReplicator::GetLocalReplicator(*GetWorld()))
{
Replicator->ApplyCheat(ControlledActor, Actors, Cheat);
}
}