// Copyright Epic Games, Inc. All Rights Reserved. #include "LyraCheatManager.h" #include "LyraPlayerController.h" #include "LyraDebugCameraController.h" #include "Engine/Engine.h" #include "Engine/World.h" #include "Engine/Console.h" #include "GameFramework/HUD.h" #include "System/LyraAssetManager.h" #include "System/LyraGameData.h" #include "LyraGameplayTags.h" #include "AbilitySystem/LyraAbilitySystemComponent.h" #include "AbilitySystemGlobals.h" #include "GameplayEffect.h" #include "Character/LyraHealthComponent.h" #include "Character/LyraPawnExtensionComponent.h" #include "System/LyraSystemStatics.h" #include "Development/LyraDeveloperSettings.h" DEFINE_LOG_CATEGORY(LogLyraCheat); namespace LyraCheat { static const FName NAME_Fixed = FName(TEXT("Fixed")); static bool bEnableDebugCameraCycling = false; static FAutoConsoleVariableRef CVarEnableDebugCameraCycling( TEXT("LyraCheat.EnableDebugCameraCycling"), bEnableDebugCameraCycling, TEXT("If true then you can cycle the debug camera while running the game."), ECVF_Cheat); static bool bStartInGodMode = false; static FAutoConsoleVariableRef CVarStartInGodMode( TEXT("LyraCheat.StartInGodMode"), bStartInGodMode, TEXT("If true then the God cheat will be applied on begin play"), ECVF_Cheat); }; ULyraCheatManager::ULyraCheatManager() { DebugCameraControllerClass = ALyraDebugCameraController::StaticClass(); } void ULyraCheatManager::InitCheatManager() { Super::InitCheatManager(); #if WITH_EDITOR if (GIsEditor) { APlayerController* PC = GetOuterAPlayerController(); for (const FLyraCheatToRun& CheatRow : GetDefault()->CheatsToRun) { if (CheatRow.Phase == ECheatExecutionTime::OnCheatManagerCreated) { PC->ConsoleCommand(CheatRow.Cheat, /*bWriteToLog=*/ true); } } } #endif if (LyraCheat::bStartInGodMode) { God(); } } void ULyraCheatManager::CheatOutputText(const FString& TextToOutput) { #if USING_CHEAT_MANAGER // Output to the console. if (GEngine && GEngine->GameViewport && GEngine->GameViewport->ViewportConsole) { GEngine->GameViewport->ViewportConsole->OutputText(TextToOutput); } // Output to log. UE_LOG(LogLyraCheat, Display, TEXT("%s"), *TextToOutput); #endif // USING_CHEAT_MANAGER } void ULyraCheatManager::Cheat(const FString& Msg) { if (ALyraPlayerController* LyraPC = Cast(GetOuterAPlayerController())) { LyraPC->ServerCheat(Msg.Left(128)); } } void ULyraCheatManager::CheatAll(const FString& Msg) { if (ALyraPlayerController* LyraPC = Cast(GetOuterAPlayerController())) { LyraPC->ServerCheatAll(Msg.Left(128)); } } void ULyraCheatManager::PlayNextGame() { ULyraSystemStatics::PlayNextGame(this); } void ULyraCheatManager::EnableDebugCamera() { Super::EnableDebugCamera(); } void ULyraCheatManager::DisableDebugCamera() { FVector DebugCameraLocation; FRotator DebugCameraRotation; ADebugCameraController* DebugCC = Cast(GetOuter()); APlayerController* OriginalPC = nullptr; if (DebugCC) { OriginalPC = DebugCC->OriginalControllerRef; DebugCC->GetPlayerViewPoint(DebugCameraLocation, DebugCameraRotation); } Super::DisableDebugCamera(); if (OriginalPC && OriginalPC->PlayerCameraManager && (OriginalPC->PlayerCameraManager->CameraStyle == LyraCheat::NAME_Fixed)) { OriginalPC->SetInitialLocationAndRotation(DebugCameraLocation, DebugCameraRotation); OriginalPC->PlayerCameraManager->ViewTarget.POV.Location = DebugCameraLocation; OriginalPC->PlayerCameraManager->ViewTarget.POV.Rotation = DebugCameraRotation; OriginalPC->PlayerCameraManager->PendingViewTarget.POV.Location = DebugCameraLocation; OriginalPC->PlayerCameraManager->PendingViewTarget.POV.Rotation = DebugCameraRotation; } } bool ULyraCheatManager::InDebugCamera() const { return (Cast(GetOuter()) ? true : false); } void ULyraCheatManager::EnableFixedCamera() { const ADebugCameraController* DebugCC = Cast(GetOuter()); APlayerController* PC = (DebugCC ? ToRawPtr(DebugCC->OriginalControllerRef) : GetOuterAPlayerController()); if (PC && PC->PlayerCameraManager) { PC->SetCameraMode(LyraCheat::NAME_Fixed); } } void ULyraCheatManager::DisableFixedCamera() { const ADebugCameraController* DebugCC = Cast(GetOuter()); APlayerController* PC = (DebugCC ? ToRawPtr(DebugCC->OriginalControllerRef) : GetOuterAPlayerController()); if (PC && PC->PlayerCameraManager) { PC->SetCameraMode(NAME_Default); } } bool ULyraCheatManager::InFixedCamera() const { const ADebugCameraController* DebugCC = Cast(GetOuter()); const APlayerController* PC = (DebugCC ? ToRawPtr(DebugCC->OriginalControllerRef) : GetOuterAPlayerController()); if (PC && PC->PlayerCameraManager) { return (PC->PlayerCameraManager->CameraStyle == LyraCheat::NAME_Fixed); } return false; } void ULyraCheatManager::ToggleFixedCamera() { if (InFixedCamera()) { DisableFixedCamera(); } else { EnableFixedCamera(); } } void ULyraCheatManager::CycleDebugCameras() { if (!LyraCheat::bEnableDebugCameraCycling) { return; } if (InDebugCamera()) { EnableFixedCamera(); DisableDebugCamera(); } else if (InFixedCamera()) { DisableFixedCamera(); DisableDebugCamera(); } else { EnableDebugCamera(); DisableFixedCamera(); } } void ULyraCheatManager::CycleAbilitySystemDebug() { APlayerController* PC = Cast(GetOuterAPlayerController()); if (PC && PC->MyHUD) { if (!PC->MyHUD->bShowDebugInfo || !PC->MyHUD->DebugDisplay.Contains(TEXT("AbilitySystem"))) { PC->MyHUD->ShowDebug(TEXT("AbilitySystem")); } PC->ConsoleCommand(TEXT("AbilitySystem.Debug.NextCategory")); } } void ULyraCheatManager::CancelActivatedAbilities() { if (ULyraAbilitySystemComponent* LyraASC = GetPlayerAbilitySystemComponent()) { const bool bReplicateCancelAbility = true; LyraASC->CancelInputActivatedAbilities(bReplicateCancelAbility); } } void ULyraCheatManager::AddTagToSelf(FString TagName) { FGameplayTag Tag = FLyraGameplayTags::FindTagByString(TagName, true); if (Tag.IsValid()) { if (ULyraAbilitySystemComponent* LyraASC = GetPlayerAbilitySystemComponent()) { LyraASC->AddDynamicTagGameplayEffect(Tag); } } else { UE_LOG(LogLyraCheat, Display, TEXT("AddTagToSelf: Could not find any tag matching [%s]."), *TagName); } } void ULyraCheatManager::RemoveTagFromSelf(FString TagName) { FGameplayTag Tag = FLyraGameplayTags::FindTagByString(TagName, true); if (Tag.IsValid()) { if (ULyraAbilitySystemComponent* LyraASC = GetPlayerAbilitySystemComponent()) { LyraASC->RemoveDynamicTagGameplayEffect(Tag); } } else { UE_LOG(LogLyraCheat, Display, TEXT("RemoveTagFromSelf: Could not find any tag matching [%s]."), *TagName); } } void ULyraCheatManager::DamageSelf(float DamageAmount) { if (ULyraAbilitySystemComponent* LyraASC = GetPlayerAbilitySystemComponent()) { ApplySetByCallerDamage(LyraASC, DamageAmount); } } void ULyraCheatManager::DamageTarget(float DamageAmount) { if (ALyraPlayerController* LyraPC = Cast(GetOuterAPlayerController())) { if (LyraPC->GetNetMode() == NM_Client) { // Automatically send cheat to server for convenience. LyraPC->ServerCheat(FString::Printf(TEXT("DamageTarget %.2f"), DamageAmount)); return; } FHitResult TargetHitResult; AActor* TargetActor = GetTarget(LyraPC, TargetHitResult); if (ULyraAbilitySystemComponent* LyraTargetASC = Cast(UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(TargetActor))) { ApplySetByCallerDamage(LyraTargetASC, DamageAmount); } } } void ULyraCheatManager::ApplySetByCallerDamage(ULyraAbilitySystemComponent* LyraASC, float DamageAmount) { check(LyraASC); TSubclassOf DamageGE = ULyraAssetManager::GetSubclass(ULyraGameData::Get().DamageGameplayEffect_SetByCaller); FGameplayEffectSpecHandle SpecHandle = LyraASC->MakeOutgoingSpec(DamageGE, 1.0f, LyraASC->MakeEffectContext()); if (SpecHandle.IsValid()) { SpecHandle.Data->SetSetByCallerMagnitude(FLyraGameplayTags::Get().SetByCaller_Damage, DamageAmount); LyraASC->ApplyGameplayEffectSpecToSelf(*SpecHandle.Data.Get()); } } void ULyraCheatManager::HealSelf(float HealAmount) { if (ULyraAbilitySystemComponent* LyraASC = GetPlayerAbilitySystemComponent()) { ApplySetByCallerHeal(LyraASC, HealAmount); } } void ULyraCheatManager::HealTarget(float HealAmount) { if (ALyraPlayerController* LyraPC = Cast(GetOuterAPlayerController())) { FHitResult TargetHitResult; AActor* TargetActor = GetTarget(LyraPC, TargetHitResult); if (ULyraAbilitySystemComponent* LyraTargetASC = Cast(UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(TargetActor))) { ApplySetByCallerHeal(LyraTargetASC, HealAmount); } } } void ULyraCheatManager::ApplySetByCallerHeal(ULyraAbilitySystemComponent* LyraASC, float HealAmount) { check(LyraASC); TSubclassOf HealGE = ULyraAssetManager::GetSubclass(ULyraGameData::Get().HealGameplayEffect_SetByCaller); FGameplayEffectSpecHandle SpecHandle = LyraASC->MakeOutgoingSpec(HealGE, 1.0f, LyraASC->MakeEffectContext()); if (SpecHandle.IsValid()) { SpecHandle.Data->SetSetByCallerMagnitude(FLyraGameplayTags::Get().SetByCaller_Heal, HealAmount); LyraASC->ApplyGameplayEffectSpecToSelf(*SpecHandle.Data.Get()); } } ULyraAbilitySystemComponent* ULyraCheatManager::GetPlayerAbilitySystemComponent() const { if (ALyraPlayerController* LyraPC = Cast(GetOuterAPlayerController())) { return LyraPC->GetLyraAbilitySystemComponent(); } return nullptr; } void ULyraCheatManager::DamageSelfDestruct() { if (ALyraPlayerController* LyraPC = Cast(GetOuterAPlayerController())) { if (const ULyraPawnExtensionComponent* PawnExtComp = ULyraPawnExtensionComponent::FindPawnExtensionComponent(LyraPC->GetPawn())) { if (PawnExtComp->IsPawnReadyToInitialize()) { if (ULyraHealthComponent* HealthComponent = ULyraHealthComponent::FindHealthComponent(LyraPC->GetPawn())) { HealthComponent->DamageSelfDestruct(); } } } } } void ULyraCheatManager::God() { if (ALyraPlayerController* LyraPC = Cast(GetOuterAPlayerController())) { if (LyraPC->GetNetMode() == NM_Client) { // Automatically send cheat to server for convenience. LyraPC->ServerCheat(FString::Printf(TEXT("God"))); return; } if (ULyraAbilitySystemComponent* LyraASC = LyraPC->GetLyraAbilitySystemComponent()) { const FGameplayTag Tag = FLyraGameplayTags::Get().Cheat_GodMode; const bool bHasTag = LyraASC->HasMatchingGameplayTag(Tag); if (bHasTag) { LyraASC->RemoveDynamicTagGameplayEffect(Tag); } else { LyraASC->AddDynamicTagGameplayEffect(Tag); } } } } void ULyraCheatManager::UnlimitedHealth(int32 Enabled) { if (ULyraAbilitySystemComponent* LyraASC = GetPlayerAbilitySystemComponent()) { const FGameplayTag Tag = FLyraGameplayTags::Get().Cheat_UnlimitedHealth; const bool bHasTag = LyraASC->HasMatchingGameplayTag(Tag); if ((Enabled == -1) || ((Enabled > 0) && !bHasTag) || ((Enabled == 0) && bHasTag)) { if (bHasTag) { LyraASC->RemoveDynamicTagGameplayEffect(Tag); } else { LyraASC->AddDynamicTagGameplayEffect(Tag); } } } }