229 lines
8.7 KiB
C++
229 lines
8.7 KiB
C++
// ©2022 Batty Bovine Productions, LLC. All Rights Reserved.
|
|
|
|
#include "BugPlacerPawn.h"
|
|
|
|
#include "BugMarkerActor.h"
|
|
#include "BugMarkerSubsystem.h"
|
|
#include "EngineUtils.h"
|
|
#include "ExitingBugPlacementScreen.h"
|
|
#include "UnrealzillaGlobalSettings.h"
|
|
|
|
#include "Components/MaterialBillboardComponent.h"
|
|
#include "Components/SphereComponent.h"
|
|
#include "GameFramework/Character.h"
|
|
#include "GameFramework/FloatingPawnMovement.h"
|
|
#include "HAL/IConsoleManager.h"
|
|
#include "Kismet/GameplayStatics.h"
|
|
|
|
|
|
ABugPlacerPawn::ABugPlacerPawn()
|
|
{
|
|
this->PrimaryActorTick.bCanEverTick = true;
|
|
|
|
this->bArbitraryPlacement = false;
|
|
this->bCurrentTraceHit = false;
|
|
|
|
this->SphereComponent = CreateDefaultSubobject<USphereComponent>("SphereCollision");
|
|
this->SphereComponent->SetCollisionProfileName(UCollisionProfile::Pawn_ProfileName);
|
|
this->SphereComponent->CanCharacterStepUpOn = ECanBeCharacterBase::ECB_No;
|
|
this->SphereComponent->SetShouldUpdatePhysicsVolume(true);
|
|
this->SphereComponent->SetCanEverAffectNavigation(false);
|
|
this->SphereComponent->bDynamicObstacle = false;
|
|
this->RootComponent = this->SphereComponent;
|
|
|
|
this->PlacementMarkerRoot = CreateDefaultSubobject<USceneComponent>("PlacementMarkerRoot");
|
|
this->PlacementMarkerRoot->AttachToComponent(this->RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
|
|
|
|
this->LaserGlow = CreateDefaultSubobject<UMaterialBillboardComponent>("LaserGlow");
|
|
this->LaserGlow->AttachToComponent(this->PlacementMarkerRoot, FAttachmentTransformRules::KeepRelativeTransform);
|
|
|
|
this->TraceOriginComponent = CreateDefaultSubobject<USceneComponent>("TraceOrigin");
|
|
this->TraceOriginComponent->AttachToComponent(this->RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
|
|
|
|
this->PawnMovement = CreateDefaultSubobject<UFloatingPawnMovement>("MovementComponent");
|
|
if (this->PawnMovement)
|
|
{
|
|
this->PawnMovement->UpdatedComponent = this->SphereComponent;
|
|
}
|
|
}
|
|
|
|
void ABugPlacerPawn::BeginPlay()
|
|
{
|
|
this->OriginalPlayer = UGameplayStatics::GetPlayerCharacter(this, 0);
|
|
|
|
this->Activate();
|
|
|
|
Super::BeginPlay();
|
|
}
|
|
|
|
void ABugPlacerPawn::TraceTimerElapsed()
|
|
{
|
|
const UWorld *World = this->GetWorld();
|
|
|
|
if (this->bArbitraryPlacement)
|
|
{
|
|
this->TraceOriginComponent->SetVisibility(false, true);
|
|
this->PlacementMarkerRoot->SetVisibility(true, true);
|
|
this->LaserGlow->SetVisibility(false, true);
|
|
|
|
// If the debugger requests arbitrary placement, put the marker a set distance away from the camera.
|
|
this->PlacementMarkerRoot->SetRelativeLocation(FVector(GetDefault<UUnrealzillaGlobalSettings>()->ArbitraryBugPlacementDistance, 0.0f, 0.0f));
|
|
this->PlacementMarkerRoot->SetWorldRotation(FRotator::ZeroRotator);
|
|
}
|
|
else
|
|
{
|
|
// Under normal circumstances, we place the marker at the point where a laser hits a surface.
|
|
this->TraceOriginComponent->SetVisibility(true, true);
|
|
this->LaserGlow->SetVisibility(true, true);
|
|
|
|
FCollisionQueryParams Params;
|
|
Params.bTraceComplex = false;
|
|
Params.bIgnoreTouches = false;
|
|
Params.AddIgnoredActor(this);
|
|
|
|
FHitResult TraceHit;
|
|
const FVector TraceStart = this->GetActorLocation();
|
|
const FVector TraceEnd = TraceStart + (this->GetActorForwardVector() * GetDefault<UUnrealzillaGlobalSettings>()->BugPlacementTraceDistance);
|
|
this->bCurrentTraceHit = World->LineTraceSingleByChannel(TraceHit, TraceStart, TraceEnd, ECollisionChannel::ECC_Visibility, Params);
|
|
|
|
// Move bug marker to the current pointer position, or behind
|
|
// the camera if the pointer is not currently hitting a surface.
|
|
if (this->bCurrentTraceHit)
|
|
{
|
|
if (ABugMarkerActor *Marker = Cast<ABugMarkerActor>(TraceHit.GetActor()))
|
|
{
|
|
this->PlacementMarkerRoot->SetVisibility(true, false);
|
|
this->UpdateBugInformation(Marker->GetBugData());
|
|
this->ShowDummyMarker(false);
|
|
}
|
|
else
|
|
{
|
|
this->PlacementMarkerRoot->SetVisibility(true, true);
|
|
this->UpdateBugInformation(FUnrealzillaBugData());
|
|
this->ShowDummyMarker(true);
|
|
}
|
|
|
|
this->PlacementMarkerRoot->SetWorldLocationAndRotation(TraceHit.ImpactPoint, FRotationMatrix::MakeFromZ(TraceHit.ImpactNormal).ToQuat());
|
|
this->ShowCrosshairs(false);
|
|
|
|
const FVector TraceOriginLocation = this->TraceOriginComponent->GetComponentLocation();
|
|
FVector FacingVector = (TraceHit.ImpactPoint - TraceOriginLocation);
|
|
FacingVector.Normalize();
|
|
const FRotator TraceOriginFacingRotation = FRotationMatrix::MakeFromX(FacingVector).Rotator();
|
|
this->TraceOriginComponent->SetWorldRotation(TraceOriginFacingRotation);
|
|
const FVector TraceOriginScale = this->TraceOriginComponent->GetRelativeScale3D();
|
|
this->TraceOriginComponent->SetRelativeScale3D(FVector(TraceOriginScale.X, TraceOriginScale.Y, (TraceHit.ImpactPoint - TraceOriginLocation).Length()));
|
|
}
|
|
else
|
|
{
|
|
this->PlacementMarkerRoot->SetRelativeLocationAndRotation(FVector::ZeroVector, FRotator::ZeroRotator);
|
|
this->PlacementMarkerRoot->SetVisibility(false, true);
|
|
this->ShowCrosshairs(true);
|
|
|
|
const FVector TraceOriginLocation = this->TraceOriginComponent->GetComponentLocation();
|
|
FVector FacingVector = (TraceEnd - TraceOriginLocation);
|
|
FacingVector.Normalize();
|
|
const FRotator TraceOriginFacingRotation = FRotationMatrix::MakeFromX(FacingVector).Rotator();
|
|
this->TraceOriginComponent->SetWorldRotation(TraceOriginFacingRotation);
|
|
const FVector TraceOriginScale = this->TraceOriginComponent->GetRelativeScale3D();
|
|
this->TraceOriginComponent->SetRelativeScale3D(FVector(TraceOriginScale.X, TraceOriginScale.Y, (TraceEnd - TraceStart).Length()));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void ABugPlacerPawn::SetArbitraryPlacement(bool bSet)
|
|
{
|
|
this->bArbitraryPlacement = bSet;
|
|
}
|
|
|
|
void ABugPlacerPawn::PlaceBugMarker()
|
|
{
|
|
// If there is a surface onto which to place a bug actor, then do so here.
|
|
if (this->bArbitraryPlacement || this->bCurrentTraceHit)
|
|
{
|
|
FActorSpawnParameters SpawnParams;
|
|
SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
|
|
#if WITH_EDITOR
|
|
SpawnParams.bHideFromSceneOutliner = true;
|
|
#endif
|
|
|
|
TSubclassOf<ABugMarkerActor> Class = StaticLoadClass(ABugMarkerActor::StaticClass(), nullptr, BUG_MARKER_ACTOR_BP);
|
|
ABugMarkerActor *Marker = this->GetWorld()->SpawnActor<ABugMarkerActor>(Class.Get(), this->PlacementMarkerRoot->GetComponentTransform(), SpawnParams);
|
|
Marker->LoadBugSubmissionForm();
|
|
}
|
|
}
|
|
|
|
|
|
void ABugPlacerPawn::Activate()
|
|
{
|
|
this->SavedMaxSpeed = this->PawnMovement->GetMaxSpeed();
|
|
|
|
UGameplayStatics::GetPlayerController(this, 0)->Possess(this);
|
|
|
|
const float &MinTimeDilation = this->GetWorldSettings()->MinGlobalTimeDilation;
|
|
this->GetWorldSettings()->SetTimeDilation(MinTimeDilation);
|
|
this->CustomTimeDilation = 1.0 / MinTimeDilation;
|
|
|
|
float TraceInterval = this->GetActorTickInterval() > 0.0f ? this->GetActorTickInterval() : (1.0f / 60.0f) * MinTimeDilation;
|
|
this->GetWorldTimerManager().SetTimer(this->TraceTimerHandle, this, &ABugPlacerPawn::TraceTimerElapsed, TraceInterval, true);
|
|
}
|
|
|
|
void ABugPlacerPawn::Deactivate()
|
|
{
|
|
this->GetWorldTimerManager().ClearAllTimersForObject(this);
|
|
this->GetWorldSettings()->SetTimeDilation(1.0f);
|
|
|
|
UGameplayStatics::GetPlayerController(this, 0)->Possess(this->OriginalPlayer);
|
|
|
|
this->Destroy();
|
|
}
|
|
|
|
|
|
void ABugPlacerPawn::ExitStarted()
|
|
{
|
|
this->ExitingBugPlacementScreen = CreateWidget<UExitingBugPlacementScreen>(UGameplayStatics::GetPlayerController(this, 0), this->ExitingBugPlacementScreenClass.Get());
|
|
this->ExitingBugPlacementScreen->AddToViewport(GetDefault<UUnrealzillaGlobalSettings>()->BugReportWidgetDepth + 10);
|
|
}
|
|
|
|
void ABugPlacerPawn::ExitOngoing(const float ElapsedSeconds)
|
|
{
|
|
this->ExitingBugPlacementScreen->SetPercent(ElapsedSeconds);
|
|
}
|
|
|
|
void ABugPlacerPawn::ExitTriggered()
|
|
{
|
|
this->ExitingBugPlacementScreen->RemoveFromParent();
|
|
this->Deactivate();
|
|
}
|
|
|
|
void ABugPlacerPawn::ExitCanceled()
|
|
{
|
|
this->ExitingBugPlacementScreen->RemoveFromParent();
|
|
}
|
|
|
|
|
|
void ABugPlacerPawn::SpawnBugPlacerPawn(const UObject *WorldContextObject, TSubclassOf<ABugPlacerPawn> Class)
|
|
{
|
|
const FTransform &Transform = UGameplayStatics::GetPlayerCameraManager(WorldContextObject, 0)->GetActorTransform();
|
|
FActorSpawnParameters SpawnParams;
|
|
SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
|
|
WorldContextObject->GetWorld()->SpawnActor<ABugPlacerPawn>(Class, Transform, SpawnParams);
|
|
}
|
|
|
|
void ABugPlacerPawn::ShowBugMarkersInLevel(const UObject *WorldContextObject)
|
|
{
|
|
if (UBugMarkerSubsystem *BugMarkerSubsystem = UGameplayStatics::GetPlayerController(WorldContextObject, 0)->GetLocalPlayer()->GetSubsystem<UBugMarkerSubsystem>())
|
|
{
|
|
BugMarkerSubsystem->ShowBugMarkers();
|
|
}
|
|
}
|
|
|
|
void ABugPlacerPawn::HideBugMarkersInLevel(const UObject *WorldContextObject)
|
|
{
|
|
if (UBugMarkerSubsystem *BugMarkerSubsystem = UGameplayStatics::GetPlayerController(WorldContextObject, 0)->GetLocalPlayer()->GetSubsystem<UBugMarkerSubsystem>())
|
|
{
|
|
BugMarkerSubsystem->HideBugMarkers();
|
|
}
|
|
}
|